Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind more arguments of an already bound function in Javascript

I try to sort my thoughts about how javascript's bind() works.

I see that if I do

var f = function (a) { ... } var g = f.bind(obj); g(1) 

then f is called with obj as this and 1 as a.

What I thought is g is a wrapper function around f.

But when I do

var f = function (a) { ... } var g = f.bind(obj); g.call(1) 

then f is called with 1 as this and a undefined.

So it seems g is not just a simple wrapper, but call somehow differentiates between normal and bound functions.

One more thing is I cannot partially apply a function more times.

var f = function (a) { ... } var g = f.bind(obj); var h = g.bind(1); h(); 

Then f is called with obj as this and a undefined.

What is the cause of this behavior?

Edit

The constructs in this question are actually wrong, see the accepted answer on what they should look like (in general I haven't noticed that call and bind do always need the context argument as the first argument).

like image 357
Martin Pecka Avatar asked Jan 04 '14 18:01

Martin Pecka


People also ask

What is bind () method in JavaScript?

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

How do you bind variables in JavaScript?

We use the Bind() method to call a function with the this value, this keyword refers to the same object which is currently selected . In other words, bind() method allows us to easily set which object will be bound by the this keyword when a function or method is invoked.

Should you use BIND in JavaScript?

Use bind() when you want a function that always runs with a specific this value. It's useful for more functional programming, when passing around functions as callbacks or event handlers.

What is implicit binding in JavaScript?

Implicit binding covers most of the use-cases for dealing with the this keyword. When we invoke a method of an object, we use the dot(.) notation to access it. In implicit binding, you need to check the object adjacent to the method at the invocation time. This determines what this is binding to.


1 Answers

Once you bound an object to a function with bind, you cannot override it. It's clearly written in the specs, as you can see in MDN documentation:

"The bind() function creates a new function (a bound function) with the same function body (internal call property in ECMAScript 5 terms) as the function it is being called on (the bound function's target function) with the this value bound to the first argument of bind(), which cannot be overridden."

That means, also if you do:

g.call(1); 

You will get obj as this, and not 1 – on the browsers that follows the specs.

You can of course binds multiple arguments, so:

var sum = function(a, b, c) { return a + b + c }; var sumAB = sum.bind(null, 1, 5); var sumC = sumAB.bind(null, 2);  console.log(sumC()); 

But the context object will be always the one specified with the first bind, because it cannot be overwritten.

Just to avoid confusion, the first argument of call is the context object (this), then you will have the rest of the argument.

It means:

var obj = { foo: function(bar) { console.log(bar) } };  obj.foo('hello');  // equivalent to: var foo = obj.foo;  foo.call(obj, 'hello'); 

Hope it helps.

like image 152
ZER0 Avatar answered Sep 20 '22 21:09

ZER0