Shaoz
Shaoz

Reputation: 10653

object in javascript reference by this but not when using event listener

Why is it that the this is not referencing the object, myObject?

When I do console.log(this) returns undefined... Why?

Javascript:

var myObject = {
                    
    product: document.getElementById('product'),
    
    button: document.getElementById('btn'),
    
    productView: function(){
        if (this.product.className === 'grid') {
            this.product.className = 'list';
        } else {
            this.product.className = 'grid';
        }
    },
    
    clickHandler: function(e) {
        var o = this;
        console.log(this);
        o.productView();
        e.preventDefault();
    },
    
    init: function (){
        this.button.addEventListener('click', this.clickHandler, false);
    }
};

myObject.init();​

demo

Many Thanks

Upvotes: 1

Views: 132

Answers (4)

Luke
Luke

Reputation: 19971

First just use 'this' for your click handler...

clickHandler: function(e) {
    console.log(this);
    this.productView();
    e.preventDefault();
}

Then you have a few options. Here are two...

Option A:

init: function (){
    var o = this;
    this.button.addEventListener('click', function(e){
        o.clickHandler(e);
    }, false);
}

Option B:

init: function (){
    this.button.addEventListener('click', this.clickHandler.bind(this), false);
}

I asked a related question about which of these options is preferrable: When should a JavaScript reference object be used versus .bind()?

Upvotes: 0

pimvdb
pimvdb

Reputation: 154838

Calling this.clickHandler() there would set this to the object. However, you're merely passing the function to addEventListener, and the browser will set a custom this value when it calls the function.

If you want to bind the current this value, use this.clickHandler.bind(this). The function returned by bind will also receive the "wrong" this value, but it calls clickHandler with the bound, correct this value.

Upvotes: 1

Trevor
Trevor

Reputation: 9578

You need to bind this to the correct context of you object. I common way to achieve this is to assign a reference of the local this to another variable inside your init function:

init: function (){
    var that = this;
    this.button.addEventListener('click', function(e) {that.clickHandler(e)}, false);
}

Upvotes: 2

João Gonçalves
João Gonçalves

Reputation: 4002

The .this in your handler method for the event refers to the object being clicked. Use something like var self = myObject; and then use self instead of this.

Upvotes: 3

Related Questions