socm_
socm_

Reputation: 787

Why is instance variable undefined?

I dont understand one thing:

 var comein = document.getElementById("comein");

 var enter = new Expand({ elem : comein });

function Expand (options) {
    this._elem = options.elem;
    console.log(this._elem); // i have a div element    
}

Expand.prototype = {        
    check : function () {

        var comInClassName = this._elem.className; // i have an error: this._elem is undefined

        if (comInClassName == "open"){
          this.close();
        }
        if (comInClassName == "close"){
          this.open();
        }
    }
}
log_in.addEventListener("click",  enter.check, false);

Why I have an error in prototype method if in Expand i have a normal element? Thanks

Upvotes: 0

Views: 1169

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074495

It depends entirely on how you call check. If you call it like this:

enter.check();

....then within the call, this will refer to the enter object and it will have an _elem property. If, on the other hand, you set it up to be called like this:

enter._elem.addEventListener('click', enter.check, false);

...then within the call (when the event occurs), this will not refer to enter, but rather to this._elem, and so it has no _elem property.

This happens because in JavaScript (for now), this within a function call is defined entirely by how the function is called, not where the function is defined. If you call it as part of an expression retrieving the function reference from an object:

enter.check();

...then this refers to the object you got the function reference from. But if you call it separately, as with the addEventListener call above, it doesn't.

If you're on an ECMAScript5-enabled environment (or if you have a decent ES5 shim in place), you can fix that by using Function#bind:

enter._elem.addEventListener('click', enter.check.bind(enter), false);

bind returns a function that, when called, will turn around and call the underlying function using the given this value (enter, in our case).

More to explore (on my blog):

Upvotes: 6

Related Questions