So I had a sample that wasn't working in firefox. It had code like ths
"use strict";
var devicePixelRation = window.devicePixelRatio || 1;
That worked fine on Chrome but broke on Firefox with
TypeError: setting a property that has only a getter
So first thing I learned something I didn't know. Variables declared with var
in the global scope
get added to the window object. I can't believe I've been programming web stuff for like forever and even was on the Chrome team for 5 years and didn't know this. I new variables without var
were added to the window but I didn't know globals with var
were added. They aren't added to other objects in other scopes. I'm going to have to assume this is some legacy issue they can't get rid of
But.... The bigger issue is this seems like a timebomb waiting to happen. The problem is you write some code today. Let's say you write
"use strict";
var numProcessesAvailable = 100; // Some application specific variable.
Tomorrow some new web standard comes out and decides there should be a variable on window called numProcessesAvailable
. At that point every program what was using a variable in the global scope called numProcessesAvailable
breaks.
The same would be true of adding properties to elements. If you've got code like this
"use strict"
function makeDivWithProperities(parent) {
var div = document.createElement("div");
parent.appendChild(div);
div.deviceWidth = someMagicFunctionToComputeDeviceWidth(div); // !!!
}
If tomorrow some standard decides to add deviceWidth
to all HTMLElements than any app using that name will break.
Can that really be what Firefox wants? Is there an issue filed about this somewhere? I'd like to read the thinking on this issue. It seems like it has to be the Chrome way otherwise every time a new property is added to any native browser object and you're running in strict mode you run the risk of breaking lots of web pages.
No? Thoughts?
Both Chrome and Firefox are overwriting the global variable. The difference is that Firefox blocks overwriting
devicePixelRatio
and Chrome doesn't. You'd see the same error if you did this:Strict mode exists to protect us from doing dangerous things - it throws an error to let you know early that your code is likely to cause problems, rather than fail silently.
Unless you're inside a module, which does not expose top level variables as global (not supported everywhere yet), it's (IMHO) best practice to wrap everything inside a function. That way you don't risk name collisions, either with future standards or with other code running on the same page. You only export global values on purpose if you want them to be available to other, and even that practice will be more or less deprecated as it's replaced by modules.