简体   繁体   中英

Access object property in class method

In many other questions it's explained why this in the Say method below isn't always referring to an object of Foo.

class Foo {
    constructor(){
        this.bar = "baz";
    }

    Say(){
        alert(this.bar);
    }
}

I want to make sure that Say() will result in the same alert regardless of how it's called. I only control the code above, not the examples below.

var f = new Foo();
f.Say();                                    //"baz"
element.addEventListener("click", f.Say);   //undefined
f.Say.call({bar: "no"});                    //"no"

I have a roughly idea of how to build an implementation using functions.

function Foo(){
    var bar = "baz";
    return {
        Say(){
            alert(bar);
        }
    }
}

Can this be assured using the class syntax?

Try this:

class Foo {
    constructor(){
        this.bar = "baz";
        this.Say = this.Say.bind(this);
    }

    Say(){
        alert(this.bar);
    }
}

With this, you force that the context of the Say method will always be this .

You are actually adding a new property to each Foo instance with the same name as the property Say in its prototype, so this new property will take precedence over the prototype, and setting it as the same function but with the context forced with bind.

EDIT: You can automate it with something like this:

 class Foo { constructor(){ this.bar = "baz"; Object.getOwnPropertyNames(this.constructor.prototype).forEach((i) => { if (typeof this.constructor.prototype[i] == "function" && this.constructor.prototype[i] != this.constructor) { this[i] = this.constructor.prototype[i].bind(this); } }); } Say(){ alert(this.bar); } } var f = new Foo(); f.Say(); f.Say.call({bar: "no"}); 

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