views:

35

answers:

2

hi guys,

I have my object defined as follows:

function KoolTabs() {
    this.targetName = "";
    this.activeNode = 1;
this.init = function()
{
    this.targetName = arguments[0];
    this.activeNode = (arguments[1] || 1);
    this.setEle( this.activeNode );
    this.findNodes();
}
    this.findNodes = function()
    {
        for (i=0;i<document.links.length;i++) {
            myEle = document.links[i];
              x = document.links[i].href;
              if (x.indexOf("#" + this.targetName) >= 0) {
                myEle.addEventListener('click', this.onClick, false);
              }
        }
    }
    this.onClick = function()
    {
        alert('Hello ' + this.activeNode);
    }
};

I am calling it like:

<script>
    var StockTabs = new KoolTabs;
    StockTabs.init('tabsStock', 1);
</script>

Now when i click on the object which has the method bing it says "Hello undefined"

how can i get the value of parent object activeNode?

A: 

Because in that handler this refers to the clicked element, you can maintain a reference to the origin KoolTabs object though, like this:

function KoolTabs() {
  var self = this;

Then in your handler, use that reference, like this:

this.onClick = function()
{
    alert('Hello ' + self.activeNode);
}

You can test it out here. (I commented out the setEle() call, since that code wasn't included.)

Nick Craver
+1  A: 

your onClick method is called in a different context when used as an event handler in this method- this no longer refers to your KoolTabs instance.

the easy work around is to create a closure with a self-referencing variable with a different name.

function KoolTabs() { 

    var self = this;

    this.targetName = ""; 
    this.activeNode = 1; 
    this.init = function() 
    { 
        this.targetName = arguments[0]; 
        this.activeNode = (arguments[1] || 1); 
        this.setEle( this.activeNode ); 
        this.findNodes(); 
    } 
    this.findNodes = function() 
    { 
        for (i=0;i<document.links.length;i++) { 
            myEle = document.links[i]; 
              x = document.links[i].href; 
              if (x.indexOf("#" + this.targetName) >= 0) { 
                myEle.addEventListener('click', this.onClick, false); 
              } 
        } 
    } 
    this.onClick = function() 
    { 
        // "this" refers to a different object now. use the "self" 
        // variable to reference the KoolTabs instance.
        alert('Hello ' + self.activeNode); 
    } 
}; 

if you want to get fancy, you can look at jQuery's bind method to see how it generates a function call with the proper scope applied. it would be something like

$(myEle).click( this.onClick.bind(this) ); 

and when onClick fires, this would point to what you expect it to. you would not need to define the self reference.

lincolnk
The `.bind()` you're talking about it's from jQuery, it's in ECMAScript now :)
Nick Craver
so which one is better? creating self refrence or passing as argument as per performance and memory?
KoolKabin
@KoolKabin I don't know. I tend toward `self` because I don't use jquery that much, it's simple, and to my knowledge there is nothing "wrong" with it. If I already has jquery included I'd consider `bind` as it seems "cleaner" to me for some intangible reason.
lincolnk