ES6 如何在 class 中获取 _this,在另一个上下文中

ES6 How to get _this inside class, inside another context

我正在搜索,但找不到以 ES6 方式解决此问题的正确方法。

class MyClass {
  // i can't event decalre _this/_self here
  constructor() {
     setTimeout(function(){
        // other work..
        hiUser(); // this.hiUser() or //_this.hiUser() not working
     },1000);
   }
   hiUser(){
     alert('Hi');
   }
}

您可以使用 fat arrow functions:

class MyClass {
  constructor() {
    setTimeout(() => {
      this.hiUser();
    }, 1000);
  }

  hiUser(){
    alert('Hi');
  }
}

或者您可以使用简单的 ES5's Function.prototype.bind method:

class MyClass {
  constructor() {
    setTimeout(function() {
      this.hiUser();
    }.bind(this), 1000);
  }

  hiUser(){
    alert('Hi');
  }
}

有一个 ES7 proposal to shorthand the Function.prototype.bind 方法,因此,根据您(可能)使用的转译器(例如 Babel 或 Typescript),您可以设置 ES7 标志并立即使用它:

class MyClass {
  constructor() {
    setTimeout(::function() {
      this.hiUser();
    }, 1000);
  }

  hiUser(){
    alert('Hi');
  }
}

setTimeout 可能有自己的 this 上下文。不过,您可以在构造函数中设置 _self,或使用箭头函数:

class MyClass {
    constructor () {
        var self = this;
        // etc.
    }
}

之前的答案只给了你如何修复它的代码示例;让我解释一下您的问题及其发生的原因

在您的代码示例中,setTimeout 中的函数被绑定到 setTimeout 的 this 值(在严格模式下通常为 windowundefined)。

setTimeout(function () {
    // this === window
}, 1000);

在 ES6 中,他们引入了“词法绑定”的 lambda 表达式(箭头函数)——这意味着他们借用了 this 来自外部范围的值。在你的例子中,就是 class/object.

为了利用 lambda 表达式s,它看起来像:

class Foo {

    constructor () {
        setTimeout(() => this.myMethod(), 1000);
    }

    myMethod () {
        console.log('foo');
    }
}

如果您使用 Babel 来转译您的代码,并且正在使用实验性功能,您也可以使用 ES7 的 binding 语法来解决您的问题。

如果您绑定 function/method,它会创建该函数的副本,并将 this 值绑定到您选择的任何值。这将允许您使用将绑定到您的 class/object.

function 语句

<context to be bound> :: <function to receive context>

class Foo {

    constructor () {
        setTimeout(this::function() {
            this.myMethod();
        }, 1000);
    }

    myMethod () {
        console.log('foo');
    }
}

更短的版本如下所示

constructor () {
    setTimeout(this::this.myMethod, 1000);
}

如果您仍然无法理解这一点,我建议您阅读更多关于 ES6 类 和 javascript 绑定的内容。