ES6如何在另一个上下文中获取_this内部类

时间:2015-10-01 15:54:23

标签: javascript ecmascript-6 babeljs

我正在搜索,无法找到以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');
   }
}

3 个答案:

答案 0 :(得分:10)

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

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

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

在ES6中,他们引入了lambda表达式(箭头函数),这些表达式是“ lexically bound ” - 这意味着他们从外部借用this值范围。在你的情况下,这是类/对象。

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

class Foo {

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

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

如果您使用Babel来转换代码并使用实验性功能,则可以使用ES7的绑定语法来解决您的问题。

如果绑定一个函数/方法,它会创建该函数的副本,并将this值绑定到您选择的任何值。这将允许您使用将绑定到您的类/对象的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绑定的内容。

答案 1 :(得分:3)

您可以使用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');
  }
}

答案 2 :(得分:-1)

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

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