Javascript中函数绑定和闭包之间的区别?

sac*_*024 5 javascript closures bind function

当我们需要用当前上下文对象调用javascript函数时,我看到有两个选项,如:

  1. 使用函数绑定
  2. 使用Javascript关闭

函数绑定示例

myProject.prototype.makeAjax = function() {
  $.get('http://www.example.com/todoItems', function success(items) {
   this.addItemsToList(items)
  }.bind(this));
}
Run Code Online (Sandbox Code Playgroud)

JS闭包的示例

myProject.prototype.makeAjax = function() {
  var that = this;

  $.get('http://www.example.com/todoItems', function success(items) {
   that.addItemsToList(items)
  });
}
Run Code Online (Sandbox Code Playgroud)

我想问一下:

  1. 哪两个在性能方面更好?
  2. 在编写代码时应该首选哪个?

Ian*_*Ian 2

这可能在一定程度上取决于应该优先选择哪一个。我倾向于使用后者(虽然实际上我更喜欢前者,但我们使用的一些第三方库限制了这一点)。我认为选择风格最重要的是保持一致。

需要注意的是, prototype.bind不受 IE8 及以下版本的支持,这可能会给您带来问题。

我认为就性能而言,当您在其中调用额外的函数时,我希望速度bind会慢一些,但这可能取决于浏览器优化。jsperf当他们的网站恢复时,我会尝试整理一个例子来回答这部分问题。

更新

看来 JSPerf 不会很快上线。这是我整理的一个片段,显示关闭速度更快(假设我做得正确)。关闭速度稍微快了 7 倍多。如果您在控制台打开的情况下运行,您将看到计时。

var limit = 100000;

var a = {
   val: 0,
   do: function(i) { val = i; /* Actually do some work to ensure doesn't get optimised out */ }  
};

var b = {
   myFunc: function(callback) { callback(); /* Function that's going to change this keyword */}   
};



var start = +new Date();

   for(var i = 0; i < limit; i++) {
     b.myFunc(function() {
        this.do(i);
     }.bind(a));
   };

var end =  +new Date();
var diff = end - start;
console.log("bind took " + diff + " ms");

var start = +new Date();

   for(var i = 0; i < limit; i++) {
     var that = a;
     b.myFunc(function() {
        that.do(i);
     });
   };

var end =  +new Date();
var diff = end - start;

console.log("closured took " + diff + " ms");
Run Code Online (Sandbox Code Playgroud)