Reputation: 613
I am new to javascript and I am trying to implement a complicated data structure which requires modification of scope inside various functions. Then, I came across function.prototype.bind()
. At first, I thought it was very useful. But, some of the results are unexpected. So, I wrote a demo code for testing and here is the code.
(function () {
this.t = 9.8765432
this.a = (function(){
this.t = 3.14159
this.b = (function(){return this.t;}).bind(this)
this.c = (function(){
this.t=1.23456
this.d=(function(){return t;}).bind(this)
return this
})()
return this
})()
console.log(this.a.b()) //My guess was 3.14159, at the end it is 1.23456
console.log((this.a.b.bind(this))()) //My guess was 9.8765432, at the end it is 1.23456
console.log(this.a.c.d()) //My guess was 1.23456, at the end it is 1.23456
console.log((this.a.c.d.bind(this))()) //My guess was 9.8765432, at the end it is 1.23456
return this
})();
Sadly, I guessed all the results incorrectly. This indicates I don't have enough understanding of this function. Can anyone explain it to me?
Upvotes: 2
Views: 61
Reputation: 141829
You're not creating any objects for this
to refer to. Thus this
just refers to the global window
object everywhere in your code (it would be undefined
in strict mode). Since you only have one object, you only have one t
property which has most recently been assigned the value 1.23456
. The previous assignments were overwritten by the most recent assignment.
Try your test with the new keyword instead of IIFEs at each scope. This will create three separate objects for this
at different scopes, instead of using the global object:
new function () {
this.t = 9.8765432
this.a = new function(){
this.t = 3.14159;
this.b = function(){return this.t;}.bind(this);
this.c = new function(){
this.t = 1.23456;
this.d = function(){return this.t;}.bind(this);
return this;
};
return this;
};
console.log( this.a.b() ); // My guess was 3.14159
console.log( this.a.b.bind(this)() ); // My guess was 9.8765432
console.log( this.a.c.d() ); // My guess was 1.23456
console.log( this.a.c.d.bind(this)() ); // My guess was 9.8765432
return this;
};
Your first and third guesses are correct. Your second and fourth guesses would be correct if the function hadn't already been bound. Calling bind
on an already bound function has no effect on it. Removing the inner calls to bind gives you exactly what you expect:
new function () {
this.t = 9.8765432
this.a = new function(){
this.t = 3.14159;
this.b = function(){return this.t;};
this.c = new function(){
this.t = 1.23456;
this.d = function(){return this.t;};
return this;
};
return this;
};
console.log( this.a.b() ); // My guess was 3.14159
console.log( this.a.b.bind(this)() ); // My guess was 9.8765432
console.log( this.a.c.d() ); // My guess was 1.23456
console.log( this.a.c.d.bind(this)() ); // My guess was 9.8765432
return this;
};
Upvotes: 3