Reputation: 3491
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.
origin
eats
~465kB. origin
and 100k
references to dummyObject
eats ~1.1MB. origin.bind(dummyObject)
eats ~9.5MB.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
Reputation: 26828
First off, this is a function declaration
function foo() {
}
and this is a function expression
var foo = function() {};
Your two A
s 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