Last week in my post The context of "this" in Javascript, I gave an example to test the readers understanding of the topic:

var global = 'global example'; 
function globalExample() {
  return this.global;
}
console.log(this.global);     //outputs 'global example'
console.log(globalExample()); //outputs 'global example'

var obj = {
  global: 'obj example',
  example: globalExample
};
console.log(obj.global);    //outputs 'obj example'
console.log(obj.example()); //outputs 'obj example'
    
var obj2 = {
  global: 'obj2 example'
};
console.log(globalExample.call(this)); // outputs 'global example'
console.log(globalExample.call(obj));  // outputs 'obj example'
console.log(globalExample.call(obj2)); // outputs 'obj2 example'

In evaluating my post I realized a few things about that example. One, that it doesn't work when in Strict Mode. Two, that there are impacts of Strict Mode which never occurred to me. Three, I probably shouldn't encourage naming variables global.

Strict Mode

I write all my Javascript in Strict Mode because it helps to keep your code from falling into some common pitfalls, removes some of the bad parts of Javascript, and better reflects the way Javascript should/will work in future releases.

An example of imposing Strict Mode on your code is as follows:

'use strict'; //Enables strict mode
variableWithoutVar = 'content'; //Uncaught ReferenceError: variableWithoutVar is not defined

In that example, variableWithoutVar is having a value set to it before being defined. This is invalid, and without Strict Mode can result in surprising behavior (variables getting attached to the global object). Check out the Mozilla Developer Network article for many other areas that Strict Mode affects.

Strict Mode and this

What didn't occur to me when writing my example, is that with Strict Mode enabled this changed in the browser. My example breaks.

'use strict';
var global = 'global example'; 
function globalExample() {
  return this.global;
}
console.log(this.global);     //outputs 'global example'
console.log(globalExample()); //Uncaught TypeError: Cannot read property 'global' of undefined

When I applied Strict Mode to my example, the this reference I was using in globalExample is now undefined. There are a couple reasons why this behavior makes sense.

First, it forces the developer to code their functions more intentionally. When you want an object context for a function, specify it. Javascript makes this easy to do, and it would be very rare that you'd even attempt the example I made (I only realized the possible error of it now, after writing in Strict Mode for years). You get it supplied for you when defining a method on an object, or when specifying an object when using call or apply.

Second, it removes best intentioned behavior only useful to beginners. According to the Mozilla Developer Network reference, the value passed as this was being coerced into an object (so this became a reference to the global object). Behaviors like this are often in languages to help beginners deal with unexpected behavior. "What if the user doesn't know to perform a particular behavior? We'll default it for them". Making these kind of decisions often result in unexpected and insecure consequences, and other languages have had to deal with the repercussions of their helpfulness as well (see PHP's magic quotes for example).

Sorry beginners

The only downside I see to the change in behavior is probably the reason it worked the way it did before Strict Mode. The way it now works is a little confusing to a new Javascript user.

I can set this properties at the root global scope, either by defining a variable

var myVariable = 'foo';

Or by setting it as a property of this.

this.myVarialbe = 'foo';

But when in a function call, I can't use it.

this.myVariable = 'foo'; 
function example() { 
  return this.myVariable; 
} 
example(); //Uncaught TypeError: Cannot read property 'myVariable' of undefined

But then I can use it if I remove this

this.myVariable = 'foo'; 
function example() { 
  return myVariable; 
} 
example(); //no problem

So is it a closure? Is it implicitly rewriting the definition to use the global object? Truthfully, I don't know the specifics of that answer (but if you know how the js engine interprets it, please comment!). What I know is that it's the unfortunate quirky looking consequence of introducing a more stable behavior into the language.

An aside about global as a variable name

In my example, I used global as a variable name to express the nature of the variable. It was being used globally, and was defined in multiple contexts with different values.

It was an unfortunate choice if you were to try that example in node.js, because it would overwrite the node.js reference to the global object. In the browser, window references the global object. In node.js, global does. So while global is a valid variable identifier, avoiding its use could probably be considered a best practice (at least when making Javascript examples).

For more on the global object, you can read about it in Speaking JS.

Conclusion

When writing Javascript, whether it's production code, a toy example or application, or just writing a snippet in a blog post, there's no practical reason not to write your code in Strict Mode. It's the way Javascript should be written moving forward so all examples should comply with it.

Do you write all your code in Strict Mode? Feel there's a reason not to? I'm happy to debate the topic if you want to post a comment!