为什么我的原型这么慢?

Why are my prototypes so slow?

好的,所以我写了这个简单的 javascript 函数来使我的代码更具可读性:

Number.prototype.isBetween=function(a,b){
    return(this>=a&&this<b);
};

结果证明这很慢:我尝试了这个 "benchmark"(我真的不知道如何正确地做这些事情,但这无论如何都证明了我的观点):

var res=0;
var k=20;
var t=new Date().getTime();
for(var i=0;i<10000000;i++){if(k.isBetween(13,31)){res++;}}
console.log(new Date().getTime()-t);

对比

var res=0;
var k=20;
var t=new Date().getTime();
for(var i=0;i<10000000;i++){if(k>=13&&k<31)){res++;}}
console.log(new Date().getTime()-t);

并且第一个脚本在 chrome 中大约需要 3000 毫秒(chrome 是我正在使用的和我感兴趣的),而第二个脚本只需要 24 毫秒 - 一个整体因子 125 更快。扩展现有的 类 javascript 只是一个非常糟糕的主意吗?这是怎么回事?

原因是要应用方法isBetween,需要将主体k转换为Number客体。这称为拳击primitive wrapping

然后应用 isBetween 方法,其中比较运算符 > 需要从 this 对象中检索原始值,...两次。

这是附加函数调用(涉及堆栈)之上的所有附加开销。

这个总开销比需要进行的实际比较要多,因此对性能的影响相对较大。

严格模式

正如@Bergi 在下面的评论中提到的,above-described 包装 does not happen in strict mode MDN :

the value passed as this to a function in strict mode is not forced into being an object (a.k.a. "boxed"). [...] automatic boxing [is] a performance cost [...] Thus for a strict mode function, the specified this is not boxed into an object.

你会发现当切换到严格模式时,增加的性能成本会消失:

"use strict";