简体   繁体   中英

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

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 .

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);
}

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.

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()?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM