javascript - 为什么 "use strict"在此示例中将性能提高 10 倍?

标签 javascript performance

跟随问题Extending String.prototype performance我真的很感兴趣,因为仅仅将 "use strict" 添加到 String.prototype 方法就可以将性能提高 10 倍。 explanation通过 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

最佳答案

In strict mode, the this context is not forced to be an object.如果您在非对象上调用函数,this 将只是那个非对象。

相比之下,在非严格模式下,如果 this 上下文还不是一个对象,它总是先包装在一个对象中。例如,(42).toString() 首先将 42 包装在一个 Number 对象中,然后调用 Number.prototype.toStringNumber 对象作为 this 上下文。在严格模式下,this 上下文保持不变,只是调用 Number.prototype.toString 并将 42 作为 this上下文。

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

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

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

关于javascript - 为什么 "use strict"在此示例中将性能提高 10 倍?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38411552/

相关文章:

mysql - 如何使用组合索引进行昂贵的聚合查询?

performance - Couchdb 1.5 和 Node JS 查询服务器

javascript - .params 到底是什么以及它有什么作用?

javascript - 是否有可以确定 IP 地理位置的 node.js 模块?

jquery - Mailchimp 需要 140kb 才能加载

performance - sqlite 在 SSD 磁盘上更新缓慢(1720 条记录需要 15 秒)

javascript - HTML5 输入类型时间——选择或更改了哪一部分(小时或分钟)?

javascript - 强制 % 进入文本框,右对齐

javascript - React 向下传递钩子(Hook)会导致重新渲染并失去对输入的关注

performance - Cassandra 插入 preparedStatement 或 mapper?