我最近遇到过这个问题。对于我正在研究的项目,我们过于频繁地使用.bind()方式,考虑到渲染循环只需要16ms来完成任务,它实际上很难达到性能。
所以我做了一些jsperf并注意到调用绑定函数(除了额外的垃圾)比调用未绑定函数或在函数上使用.call要慢。
我真的改变了每一段代码以避免绑定并改为使用.call / .apply。丁这个我不仅产生了较少的功能,而且还提高了我的应用程序的性能。
但是,我对此并不满意,并编写了一种新的绑定函数的方法。 https://github.com/SebastianNette/FastBind
这是使用.call / .apply方法覆盖本机绑定方法。 它的运行速度提高了96%。
对nodejs进行一些测试得出以下结果: 调用绑定函数比调用未绑定函数慢20倍。 使用我自己的方法调用绑定函数只需要未绑定调用的2倍。
所以我想知道本机绑定功能有什么问题。为什么它表现得那样?这将是处理该问题的最佳方式。
我的大多数应用代码现在都是这样编写的:
var scope = this;
this.boundFn = function(a,b,c) { return scope.fn(a,b,c); };
甚至
this.callback = fn;
this.context = context;
this.callback.call(this.context);
我更喜欢后者,因为它不会产生任何新功能。但是,有时我只是必须绑定。 (处理程序,计时器等)。
答案 0 :(得分:0)
我受过教育的猜测是,它会复制您正在使用的对象,但会替换对象的基础原型。现在,它不需要使用页面呈现代码中的通用预编译对象,而是需要做两件事:
传递的变量即将到来。分析它,克隆它。然后将要调用的指定函数注入新对象。然后在新对象中执行该函数。之后如果不再叫它清理它。
对象具有更复杂和更多的范围循环,绑定将花费很长时间,因为引擎需要遍历所有函数和参数的范围树以查看需要复制的内容。
您已经在使用范围,我强烈建议。内存强度较低,引擎无需复制对象,然后调用函数。而且您可以获得额外的好处,即可以从两个对象访问属性。
根据我的经验,从未真正需要绑定。只需使用setter和getter作为属性,否则作用域变量并不总是在主对象中更改。
以此片段为例
function domagic() {
this.myproperty = "Hello ";
}
domagic.prototype = {
perform:function(){
var that = this;
var hello = "World";
setTimeout(function(){
// this in this contect is whatever runs timeout. not domagic
// I use this for jQuery and my own objects to get best
// of both worlds, but I always post a comment in a scope
// to remind myself what this and that refers to.
window.alert(that.myproperty+hello);
that.set("Goodbye ");
},2000);
},
set : function(what) {
this.myproperty = what;
}
};
magic = new domagic();
magic.perform();
setTimeout(function(){magic.perform();},2000);