【问题标题】:Methods in ES6 objects: using arrow functionsES6 对象中的方法:使用箭头函数
【发布时间】:2019-06-27 22:58:47
【问题描述】:

在 ES6 中,这两个都是合法的:

var chopper = {
    owner: 'Zed',
    getOwner: function() { return this.owner; }
};

并且,作为简写:

var chopper = {
    owner: 'Zed',
    getOwner() { return this.owner; }
}

是否也可以使用新的箭头功能?在尝试类似

var chopper = {
    owner: 'John',
    getOwner: () => { return this.owner; }
};

var chopper = {
    owner: 'John',
    getOwner: () => (this.owner)
};

我收到一条错误消息,提示该方法无权访问this。这只是语法问题,还是不能在 ES6 对象中使用粗箭头方法?

【问题讨论】:

  • 在使用粗箭头语法时?仅当您通过首先创建 chopper 对象,然后在 this 指向该对象的函数中执行赋值来更改 this 值时。这可以通过构造函数非常干净地完成。
  • 此演示将在 Firefox 中运行。 Chrome 还没有。 jsfiddle.net/bfyarxfe
  • @fox,你必须在那个 jsfiddle 上使用'use strict'。
  • @fox:它在受支持的环境中运行良好。 Firefox 还没有完全的支持。在Continuumconsole.log() 方法调用的结果中试一试。它有效。
  • Mozilla 文档说 没有自己的 this 或 super 绑定,不应该用作方法 Mozilla Arrow function documentation

标签: javascript ecmascript-6 ecmascript-harmony


【解决方案1】:

箭头函数并非设计用于在所有情况下仅作为老式函数的较短版本。它们不打算使用 function 关键字替换函数语法。箭头函数最常见的用例是不重新定义 this 的简短“lambdas”,通常在将函数作为回调传递给某个函数时使用。

箭头函数不能用于编写对象方法,因为正如您所发现的,由于箭头函数关闭了词法封闭上下文的this,因此箭头中的this 是您定义的当前位置物体。也就是说:

// Whatever `this` is here...
var chopper = {
    owner: 'Zed',
    getOwner: () => {
        return this.owner;    // ...is what `this` is here.
    }
};

在你的情况下,想要在对象上编写方法,你应该简单地使用传统的function 语法,或者 ES6 中引入的方法语法:

var chopper = {
    owner: 'Zed',
    getOwner: function() {
        return this.owner;
    }
};

// or

var chopper = {
    owner: 'Zed',
    getOwner() {
        return this.owner;
    }
};

(它们之间存在细微差别,但仅当您在getOwner 中使用super 时它们才重要,而您不是,或者如果您将getOwner 复制到另一个对象。)

在 es6 邮件列表上有一些争论,关于箭头函数的扭曲,它们具有相似的语法但有自己的 this。然而,这个提议并没有得到很好的接受,因为它只是语法糖,允许人们省去输入几个字符,并且没有提供比现有函数语法更多的功能。请参阅主题unbound arrow functions

【讨论】:

  • 如果我没看错的话,这似乎表明邮件列表会降低语法糖的优先级,即使它会导致代码的更高一致性/可读性。就目前而言,在 ES6 下的 OOP 上下文中使用胖箭头函数比在咖啡脚本下更具挑战性。
  • 据我了解,语法糖 被认为是考虑语言扩展的正当理由,但正如您所说的优先级较低 - 换句话说,标准更高对于此类提案。
  • 有点困惑。根据我对函数关键字表示法的理解, this 指向执行的上下文,它在哪里被调用,而不是在哪里定义。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 。在上面的例子中,你真的可以在this.owner 上传递等于在 chopper 对象上定义的值吗?
【解决方案2】:

在这一行getOwner: () => this.owner 应该是:

var chopper = {
    owner: 'John',
    getOwner: () => this.owner
}; //here `this` refers to `window` object.

您必须将this 声明为函数:

var chopper = {
    owner: 'John',
    getOwner() { return this.owner }
};

或者:

var chopperFn = function(){

    this.setOwner = (name) => this.owner = name;
    Object.assign(this,{
        owner: 'Jhon',
        getOwner: () => this.owner,
    })

}

var chopper = new chopperFn();
console.log(chopper.getOwner());
chopper.setOwner('Spiderman');
console.log(chopper.getOwner());

【讨论】:

  • 这里出现错误:"TypeError: Cannot read property 'owner' of undefined\n at Object.chopper.getOwner
  • 我明白了,这是正确的用法,但是方法 esta 总是返回窗口对象。您必须在函数中声明 this
  • this 不一定指的是window。它指的是this 的当前值在封闭环境中的任何值,可能是也可能不是window。也许这就是你的意思。只是想确保他明白这不是一些默认值。
  • @torazaburo 这对我来说很好,我试过了,this 现在指的是类
  • 你写的内容等价于,但比简单地写var chopperFn = function() { this.owner = 'Jhon'; this.getOwner = () => this.owner; }更冗长。
【解决方案3】:

如果非要使用箭头功能,可以将this改为chopper

var chopper = {
  owner: "John",
  getOwner: () => chopper.owner
};

虽然这不是最佳实践,但当您更改对象名称时,您必须更改此箭头功能。

【讨论】:

    【解决方案4】:

    我使用箭头函数的快速提示。

    • 对将使用object.method() 语法的方法使用非箭头函数。 (这些函数将从调用者那里接收有意义的this 值。)
    • 几乎所有其他事情都使用箭头功能。

    【讨论】:

      【解决方案5】:

      另一个提示,在严格模式下,this 仍然指的是 Window 而不是 undefined。

        (() => {
          "use strict";
          console.log(this); // window
        })();
      
        (function () {
          "use strict";
          console.log(this); // undefined
        })();
      

      【讨论】:

        【解决方案6】:

        这个内部箭头函数不反映对象的上下文。相反,它给出了调用对象方法的上下文。

        选中此项,这可以让您了解何时使用箭头,何时不使用。 https://dmitripavlutin.com/when-not-to-use-arrow-functions-in-javascript/

        【讨论】:

        • 不,对象字面量内的箭头函数内的this 指的是对象字面量所在的范围,而不是它被调用的位置。
        猜你喜欢
        • 2017-12-13
        • 2019-01-06
        • 1970-01-01
        • 2015-03-17
        相关资源
        最近更新 更多