Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Function Binding and Closure in Javascript?

When we need to call a javascript function with current context object, I see there are two options like:

  1. Using Function Binding
  2. Using Javascript Closure

Example of Function Binding

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

Example of JS Closure

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

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

I want to ask:

  1. Which of the two is better in terms of performance ?
  2. Which should be preferred while writing code ?
like image 398
Sachin Avatar asked Nov 01 '22 00:11

Sachin


1 Answers

It probably depends a little on which should be preferred. I tend to use the latter (though actually I prefer the former, but some 3rd party libraries we're using limit that). I think the important thing on picking a style is being consistent.

A note for the prototype.bind is that it's not supported by IE8 and below which might cause you a problem.

I think performance wise, I'd expect bind to be a little bit slower as you're calling an extra function in there, but it'll probably depend on browser optimizations. I'll try putting together a jsperf example when their site comes back up to answer that part of the question though.

update

Seems JSPerf isn't going to be up anytime soon. Here's an snippet that I've put together that shows the closure was quicker (assuming I've done it correct). The closure was slightly more than 7x faster. If you run with the console open you'll see the timings.

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");
like image 59
Ian Avatar answered Nov 09 '22 06:11

Ian