Javascript Scope And Self=this, _this=this, That=this
Solution 1:
The issue is that the scope
of your internal functions is not being resolved to this
, therefore, they lose all reference to the scope created at the instanciation of new PersonClass()
. The bind
method will resolve the scope
of the internal functions to this
of the parent function class.
var PersonClass = function PersonClass(_name, _age)
{
var _this=this;
this.name=_name;
this.age=_age;
console.log("created "+this.name+":"+this.age);
this.changeAge = function(num)
{
console.log("changing age for:" + _this.name);
_this.age = num;
}.bind(this);
this.getAge = function()
{
console.log(_this.name+":"+_this.age);
return _this.age;
}.bind(this);
this.getAge2 = function()
{
console.log(this.name+":"+this.age);
returnthis.age;
};
};
// comments indicate what value is displayed in consolevar john = new PersonClass("john",1); // john:1var sue = new PersonClass("sue",2); // sue:2
john.getAge(); // sue:2
john.getAge2(); // john:1
john.changeAge(10); // sue
sue.getAge(); // sue:10
sue.getAge2(); // sue:10
john.getAge(); // sue:10
john.getAge2(); // john:1
Yup, that'll do it.
Hey look, it works! Here's the updated Fiddle
Just to provide more info on bind
Lets say me have an object
:
var myObj = {};
And we assign a property to that object
:
myObj.test_property = "Hello World!";
We can access that property from other properties through bind
and this
.
Lets say we make another property that's a function
:
myObj.test_func = function()
{
alert(this.test_property);
}.bind(myObj);
Wait do you guess this will do?
Because of the bind
method, the scope of this
was resolved to myObj
.
Therefore, this.test_property
is equal to myObj.test_property
, retaining the scope.
Let's go further...
We'll declare another function:
myObj.test_func2 = function(val)
{
this.test_property = val;
}.bind(myObj);
Now, lets run a test:
myObj.test_func();
myObj.test_func2("Hello Dude");
myObj.test_func();
As you can see, both test_func
and test_func2
share the same scope.
Here's a JSFiddle illustrating everything I've said about bind
Solution 2:
When you call
new PersonClass()
at first time, prototype methods are created.
When you call
new PersonClass()
second time, prototype methods are replaced and now they has last _this in closure scope.
So, move prototype methods outside constructor function.
Solution 3:
There are quite a few issues with your code.
_this=this;
Creates a global variable
window._this
. Use a tools like jshint to avoid this kind of bugs.PersonClass.prototype
should not be used in a constructor function. You're mixing two different object creation patterns. Inside a construction function you should use something likethis.getAge2 = function(){...}
Not necessarily a bug, but for your sample code binding this to _this is not required. This will only used when your function is not invoked on the object you've created, for example, using something like
window.setTimeout(john.getAge, 100)
This causes the getAge function to become unbound from the john object when invoked.
Here's your code with the discussed changes (that is not to say that I recommend this pattern):
varPersonClass = functionPersonClass(_name, _age) {
var _this=this;
this.name=_name;
this.age=_age;
console.log("created "+this.name+":"+this.age);
functionchangeAge(num) {
console.log("changing age for:" + _this.name);
_this.age=num;
}
this.changeAge=changeAge;
this.getAge=function() {
console.log(_this.name+":"+_this.age);
return _this.age;
};
this.getAge2=function() {
console.log(this.name+":"+this.age);
returnthis.age;
};
};
var john=newPersonClass("john",1); // john:1var sue=newPersonClass("sue",2); // sue:2
john.getAge(); // john:1
john.getAge2(); // john:1
john.changeAge(10); // john
sue.getAge(); // sue:2
sue.getAge2(); // sue:2
john.getAge(); // john:10
john.getAge2(); // john:10window.setTimeout(john.getAge, 200); //john:10window.setTimeout(john.getAge2, 400); // incorrect
Post a Comment for "Javascript Scope And Self=this, _this=this, That=this"