Skip to content

Instantly share code, notes, and snippets.

@greggman
Last active August 29, 2015 14:18
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save greggman/15b5285fab6e0ca0a799 to your computer and use it in GitHub Desktop.
Save greggman/15b5285fab6e0ca0a799 to your computer and use it in GitHub Desktop.
Can it really be right that strict mode in JavaScript can break your code?

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?

@brianchirls
Copy link

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:

'use strict';
window.devicePixelRatio = 'foo';

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment