Entity Black
Entity Black

Reputation: 3491

Wrong bind techniques?

Did you ever think about what exactly bind does and if bind can be overused?

This is model of the object that is considered as a bad practise (example A):

var A = function() {
    this.foo = "foo";
    this.bar = function () {
        console.log("bar");
    };
};

This is same object written better:

var A = function() {
    this.foo = "foo";
};

A.prototype.bar = function () {
    console.log("bar");
};

Function bar is not declared over and over for each instance of A. Now look at the following snippet:

function origin() {
    console.log(this.toString() + " is who I am");
};

var listOfBindedF = [];

var dummyObject = {};

for(var i = 0; i<100;i++) {
    listOfBindedF.push(origin.bind(dummyObject));
}

With each bind usage, I declared new function didnt I? A lot of libs, frameworks and engines uses bind in its core. Not just for async calls, where it is really hard to go without bind, but literally everywhere, custom inheritance is good example.

I did short test to check it on my own.

So is there any bind performance impact on javascript apps we are doing with these frameworks/libs? Is the impact noticable? Isnt it similar to example A?

Upvotes: 1

Views: 120

Answers (1)

a better oliver
a better oliver

Reputation: 26828

First off, this is a function declaration

function foo() {
}

and this is a function expression

var foo = function() {};

Your two As are different. Imagine the following code:

function A(foo) {
  this.bar = function() {
               console.log(foo);
             };
}

This keeps foo private and still allows bar to access it, something not possible with the prototype version of A.

As for the memory issue: Each function object takes up some memory, obviously. A function expression always creates a new object. Creating 100 instances of A would create 100 function objects assigned to bar using your first example.

A function declaration creates an instance when its surrounding scope is entered. So 100 instances of A would still create 100 instances of bar in this case:

function A(foo) {
  function bar() {
    console.log(foo); 
  }
  this.bar = bar;
}

bind also creates a new function object that needs even more memory (it has to store a reference to the original function, the value for this etc.)

Using bind has an impact, but I doubt that that will ever lead to performance problems in your app. FWIW: Calling bar in your first example for A is faster then calling it in your second one, because it's not necessary to go up the prototype chain.

Please note that bind can be used for currying as well, making it a versatile tool:

function log(message) {
  console.log(message);
}

var logHello = log.bind(null, 'Hello');
logHello(); // prints 'Hello' to the console

Conclusion: Use the tool that's best suited for a task.

Upvotes: 2

Related Questions