为什么"使用严格"会在此示例中提高性能10倍?

exe*_*ook 127 javascript performance

扩展String.prototype性能之后,我真的很感兴趣,因为只需添加"use strict"一个String.prototype方法就可以提高性能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');
Run Code Online (Sandbox Code Playgroud)

结果:

proto: 101 ms
proto-strict: 7.5 ms
Run Code Online (Sandbox Code Playgroud)

Mat*_*ens 155

在严格模式下,this上下文不会被强制为对象.如果在非对象上调用函数this,则只是非对象.

相反,在非严格模式下,如果this上下文不是对象,则始终首先将其包装在对象中.例如,(42).toString()第一包装42在一个Number对象,然后调用Number.prototype.toStringNumber对象作为this上下文.在严格的模式下,this上下文保持不变,只是称Number.prototype.toString42作为this背景.

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

(function() {
  'use strict';
  console.log(typeof this);
}).call(42); // 'number'
Run Code Online (Sandbox Code Playgroud)

在您的情况下,非严格模式版本花费大量时间将原始strings 包装和解包到String对象包装器中并返回.另一方面,严格模式版本直接适用于原语string,从而提高了性能.

  • @IllidanS4:如果你喜欢的话,把它想象成"实际的'这个'"和"包装`这个`".对象包装器是一个永远不应该存在的kludge,所以在可能的情况下严格模式会避免它们更有意义. (6认同)
  • @zzzzBov不正确.删除`with`有助于_immensely_,因为它允许浏览器推断哪个变量表达式引用哪个变量. (2认同)
  • 对我来说似乎不直观,非对象`this`比始终对象'this`更"严格". (2认同)
  • @IllidanS4:这主要是关于`this`是`null`或`undefined`的情况,它将是草率模式下的全局对象. (2认同)