• 回顾一下 this

    回顾一下 this

    在JavaScript类中,我们将使用this关键字来引用类的实例。例如:

    1. class Toppings {
    2. ...
    3. formatToppings() { /* 实现细节 */ }
    4. list() {
    5. return this.formatToppings(this.toppings);
    6. }
    7. }

    这里的this指的是Toppings类的一个实例。 只要使用点号调用list方法,如myToppings.list(),则this.formatToppings(this.toppings)调用在类的实例上定义的formatToppings()方法。 这也将确保formatToppings内部,this指的是同一个实例。

    但是,this也可以指其他东西。有两种基本情况你应该记住。

    1. 方法调用:

      1. someObject.someMethod();

      这里,在someMethod内的this将引用someObject,这通常是你想要的。

    2. 函数调用:

      1. someFunction();

      这里,在someFunction内的this可以指不同的东西,这取决于我们是否处于“strict”模式。 不使用“strict”模式,这是指调用someFunction()的上下文,这很少是你想要的。 在“strict”模式下,this将是未定义的。

    View Example

    其中一个含义是,你不能轻易地从它的对象中分离一个方法。考虑这个例子:

    1. var log = console.log;
    2. log('Hello');

    在许多浏览器中这会报错。 这是因为log期望this指的是console ,但是当函数从console分离时,引用丢失了。

    这可以通过明确设置来固定。 一种方法是使用bind()方法,它允许您指定要用于绑定函数内的this的值。

    1. var log = console.log.bind(console);
    2. log('Hello');

    你也可以使用Function.callFunction.apply实现相同的功能,但我们不在这里讨论。

    另一个可能令人困惑的实例是匿名函数或在其他函数中声明的函数。 例如:

    1. class ServerRequest {
    2. notify() {
    3. ...
    4. }
    5. fetch() {
    6. getFromServer(function callback(err, data) {
    7. this.notify(); // 这不会生效
    8. });
    9. }
    10. }

    在上面的代码中,this不会指向期望的对象:在“strict”模式下,它将是未定义的。这引出另一个ES6特性 - 箭头函数,将在下面介绍。