Skip to content Skip to sidebar Skip to footer

Javascript Scope And Self=this, _this=this, That=this

Why is _this. not working but this. is working. I thought the whole point of _this=this was to provide a mechanism for when object functions are called, you have a 'guaranteed' r

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.

  1. _this=this;

    Creates a global variable window._this. Use a tools like jshint to avoid this kind of bugs.

  2. 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 like

    this.getAge2 = function(){...}

  3. 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"