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).
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.