3

有一个非常简单的算法,它在两种情况下的工作方式会出人意料地不同,具体取决于"use strict".

案例一

如果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

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

4

2 回答 2

3

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

因此,JavaScript 有String, Number, 和其他带有方法的对象toUpperCase, toLowerCase, 和toString. 当我们在字符串或数字上调用这些方法之一时,JavaScript 会包装相应的对象,调用该方法并返回原始结果。这一切都发生在幕后,我们通常不必担心。

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

也就是说,很多这些错误都有合理的解决方案,如果我们可以选择一些额外的安全措施,那就太好了。较旧的浏览器看到孤独的字符串“use strict”并忽略它。较新的浏览器会看到这一点并选择加入此处概述的一组新规则。

于 2016-05-01T19:10:18.567 回答
0

this不被装箱是严格模式的有意更改之一。这可以防止 JavaScript 代码访问原语,从而简化它以证明 JavaScript 片段是无害的。我猜想它也会带来轻微的速度提升。

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

于 2016-05-01T19:09:14.533 回答