为什么“使用严格”在这个例子中提高了10倍的性能?

在扩展String.prototype性能的问题之后,我非常感兴趣,因为在String.prototype方法中添加"use strict"可以提高性能10倍。 bergi的解释很短,并没有解释给我。 为什么两种几乎相同的方法之间有如此巨大的差异,只有顶部的"use strict"才有所不同? 你能否更详细地解释这个理论?

 String.prototype.count = function(char) { var n = 0; for (var i = 0; i < this.length; i++) if (this[i] == char) n++; return n; }; String.prototype.count_strict = function(char) { "use strict"; var n = 0; for (var i = 0; i < this.length; i++) if (this[i] == char) n++; return n; }; // Here is how I measued speed, using Node.js 6.1.0 var STR = '0110101110010110100111010011101010101111110001010110010101011101101010101010111111000'; var REP = 1e4; console.time('proto'); for (var i = 0; i < REP; i++) STR.count('1'); console.timeEnd('proto'); console.time('proto-strict'); for (var i = 0; i < REP; i++) STR.count_strict('1'); console.timeEnd('proto-strict'); 

结果:

 proto: 101 ms proto-strict: 7.5 ms 

在严格的模式下, this上下文不是被强制成为一个对象。 如果你在一个非对象上调用一个函数, this是非对象。

相反,在非严格模式下,如果this上下文不是一个对象,那么this上下文总是被包装在一个对象中。 例如, (42).toString()首先将Number对象包装为42 ,然后使用Number对象作为this上下文调用Number.prototype.toString 。 在严格模式下, this上下文是保持不变的,只是把Number.prototype.toString42作为this上下文来调用。

 (function() { console.log(typeof this); }).call(42); // 'object' (function() { 'use strict'; console.log(typeof this); }).call(42); // 'number'