为什么严格的模式会让如此简单的动作变得如此不同



有一个非常简单的算法,根据"use strict"的存在,它在两种情况下的工作方式截然不同。

情况1

如果func()声明在严格模式下,则控制台日志原语

"use strict";
// strict mode is on
Object.prototype.func = function() { return this; } // do nothing with the object
console.log( (4).func() ); // 4; primitive

情况2

如果func()声明在严格模式之外,则控制台会记录相同值的对象

// 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

这种差异的来源是什么?转换的原因是什么
在各种严格模式的状态下,如此简单的动作怎么会如此不同?

在这个特定的例子中,任何不是对象、函数或数组的东西都是基元。(从技术上讲,函数和数组都是对象。)基元值的问题是不能有方法。所以,你不能做类似"hello world".toUpperCase()的事情。一般来说,程序员喜欢拥有与他们正在处理的对象的任何类型相关的方法,而不是大量的全局可用函数(如parseInt)。

因此,JavaScript具有StringNumber和其他具有toUpperCasetoLowerCasetoString等方法的对象。当我们对字符串或数字调用其中一个方法时,JavaScript会包装相应的对象,调用该方法并返回一个基元结果。这一切都发生在幕后,我们通常不必担心

除非它不起作用——比如你的例子。JavaScript的早期版本中出现了一些错误,但由于向后兼容性的原因,我们无法真正改变这些错误。如果我在1995年创建了一个使用JavaScript的网站,然后在1997年改变了规则,我的网站就会突然崩溃。

也就是说,很多这样的错误都有合理的解决方案,如果我们能选择采取一些额外的安全措施,那就太好了。较旧的浏览器看到孤独的字符串"use strict",就忽略它。较新的浏览器会看到这一点,并选择使用一组新的规则,如下所示。

this未装箱是严格模式的有意更改之一。这防止了JavaScript代码访问基元,从而简化了它以证明JavaScript片段是无害的。我猜它的速度也略有提高。

有关更多详细信息,请参阅MDN。

最新更新