簡體   English   中英

這在 class 方法與箭頭 function

[英]This in class method vs arrow function

再會

我最近遇到了一個奇怪的情況,我在 class 的成員 function 上的this值是未定義的。 我知道有很多與 undefined this contexts 相關的問題,但我找不到這個問題的任何解釋。 我很想知道為什么會這樣。 In this examples, why does the arrow function implementation of the setModified function keep its this context, but the function on the class does not.

此示例在塊 class 上的setModified function 中斷

class point {
    constructor(x, y) {
        this._x = x || 0;
        this._changeEvents = [];
    }

    set changeEvent(eventFunction) {
        this._changeEvents.push(eventFunction);
    }

    set x(value) {
        this._x = value;
        this.runChangeEvent();
    }

    set y(value) {
        this._y = value;
        this.runChangeEvent();
    }

    get x() {
        return this._x;
    }

    get y() {
        return this._y;
    }

    runChangeEvent() {
        this._changeEvents.forEach(event => event(this));
    }
}

class renderItem {
    constructor(canvas) {
        this._canvas = canvas;
    }

    render(){

    }
}

class block extends renderItem {
     constructor(canvas) {
        super(canvas);
        this._modified = true;
        this._topLeft = new point(0, 0);
        this._topLeft.changeEvent = this.setModified;
    }

    //Using a method on the class as a callback, it breaks
    setModified(){
         this._modified = true;//breaks, this is undefined
         console.log(this);
     }

    //Sets
    set topLeft(value) { this._topLeft = value; }

    //Gets
    get topLeft() { return this._topLeft }
}
//Creates an instance of the block
const bl = new block(null);
bl.topLeft.x = 20;

但是,當您將setModified function 更改為箭頭 function (也在課堂上)時,它可以工作:

class point {
    constructor(x, y) {
        this._x = x || 0;
        this._y = y || 0;
        this._changeEvents = [];
    }

    set changeEvent(eventFunction) {
        this._changeEvents.push(eventFunction);
    }

    set x(value) {
        this._x = value;
        this.runChangeEvent();
    }

    set y(value) {
        this._y = value;
        this.runChangeEvent();
    }

    get x() {
        return this._x;
    }

    get y() {
        return this._y;
    }

    runChangeEvent() {
        this._changeEvents.forEach(event => event(this));
    }
}

class renderItem {
    constructor(canvas) {
        this._canvas = canvas;
    }

    render(){

    }
}

class block extends renderItem {
     constructor(canvas) {
        super(canvas);
        this._modified = true;
        //Using an arrow function on the class instance as a callback, it works
        this.setModified = () => {
            this._modified = true;//works
            console.log(this);
        };
        this._topLeft = new point(0, 0);
        this._topLeft.changeEvent = this.setModified;
    }

    //Sets
    set topLeft(value) { this._topLeft = value; }

    //Gets
    get topLeft() { return this._topLeft }
}
const bl = new block(null);
bl.topLeft.x = 20;

為什么 class 上的成員 function 會丟失此上下文,但不會丟失箭頭 function?

箭頭 function 表達式是常規 function 表達式的語法緊湊替代方案,盡管沒有與 this、arguments、super. 或 new.target 關鍵字的綁定。

箭頭 function 的 scope 與常規的 function 沒有什么不同,但正如您從MDN上面看到的那樣,它們處理this不同的綁定。

箭頭 function 不會創建自己的綁定this ,實際上它繼承自封閉的 scope (這是類)。 在 class 中,存在this._modified

箭頭 function 沒有自己的 this。 使用封閉詞法 scope 的 this 值; 箭頭函數遵循正常的變量查找規則。

this是在執行上下文中確定的,正如我們所示,箭頭 function 有效,因為this與封閉的 scope 的this保持一致。 但是,使用普通的 function...

然而,在嚴格模式下,如果在進入執行上下文時沒有設置 this 的值,它仍然是未定義的

如果您在 function 中的錯誤之前console.log(this)您將看到它是undefined 但為什么它是undefined的? 在隱式丟失部分閱讀此處 但基本上默認綁定在調用它作為普通的、未裝飾的 function 引用時應用,它來自分配。 在嚴格模式下, this將返回undefined而不是在全局 scope 中。

在您的情況下不會發生隱式綁定, this可能會隱式丟失。

此綁定造成的最常見的挫折之一是隱式綁定的 function 失去該綁定,這通常意味着它回退到全局 object 或未定義的默認綁定,具體取決於嚴格模式。

如果您將runChangeEvent()中的調用更改為event.call(this) ,您將看到this實際上是point的 this(不是您想要的)。 如果你調用this._topLeft.changeEvent = this.setModified.bind(this); 您將擁有您想要的 scope。

Calling f.bind(someObject) creates a new function with the same body and scope as f, but where this occurs in the original function, in the new function it is permanently bound to the first argument of bind, regardless of how the function is正在使用。

查看該鏈接以獲取更多信息,我還推薦前面提到的這本在線書籍

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM