Search code examples
javascriptgoogle-chromeuse-strictstrict-mode

Why does strict mode make such simple actions such different?


There is an extremely simple algorythm, which works surprisely different in two cases, depending on the presence of "use strict".

Case 1:

If func() declaration is within the strict mode, than console logs primitive

"use strict";

// strict mode is on
Object.prototype.func = function() { return this; } // do nothing with the object

console.log( (4).func() ); // 4; primitive

Case 2:

If func() declaration is outside the strict mode, than console logs object of the same value

// strict mode is off
Object.prototype.func = function() { return this; } // do nothing with the object

"use strict";

console.log( (4).func() ); // Number {[[PrimitiveValue]]: 4}; object

What is the source of such difference? What is the reason for this conversion?
How can such simple actions be so different in various states of strict mode?


Solution

  • In this particular example, anything that's not an object, function, or array is a primitive. (Functions and arrays are technically objects.) The problem with primitive values is that you can't have methods. So, you couldn't do something like "hello world".toUpperCase(). Generally speaking, programmers like having methods that relate to whatever type of their object they're working with than a ton of globally-available functions (like parseInt) for instance.

    So, JavaScript has String, Number, and other objects with methods like toUpperCase, toLowerCase, and toString. When we call one of these methods on a string or a number, JavaScript wraps in the corresponding object, calls the method and returns a primitive result. This all happens under the hood and we generally don't have to worry about it.

    Except when it doesn't work—like in your example. Some mistakes were made in the early versions of JavaScript, but we can't really change those things because of backwards compatibility. If I made a website in 1995 that used JavaScript and then the rules changed in 1997, my site would suddenly break.

    That said, a lot of these mistakes have reasonable solutions and it would be nice if we could opt in to some additional safety measures. Older browsers see the lonely string "use strict" and just ignore it. Newer browsers will see this and opt in to a new set of rules, outlined here.