ES6 箭头函数在原型上不起作用?

IT技术 javascript prototype ecmascript-6 arrow-functions
2021-01-19 14:30:04

当 ES6 箭头函数似乎不适用于将函数分配给具有prototype.object 的对象时。考虑以下示例:

function Animal(name, type){
 this.name = name;
  this.type = type;
  this.toString = () => `${this.name} is a ${this.type}`;

}
var myDog = new Animal('Max', 'Dog');
console.log(myDog.toString()); //Max is a Dog

在对象定义中显式使用箭头函数是有效的,但使用带有 Object.prototype 语法的箭头函数则无效:

function Animal2(name, type){
  this.name = name;
  this.type = type;
}
Animal2.prototype.toString = () => `${this.name} is a ${this.type}`;

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()); //is a undefined

正如概念证明一样,使用模板字符串语法和 Object.prototype 语法确实有效:

function Animal3(name, type){
  this.name = name;
  this.type = type;
}
Animal3.prototype.toString = function(){ return `${this.name} is a ${this.type}`;}

var myPet3 = new Animal3('Joey', 'Kangaroo');
console.log(myPet3.toString()); //Joey is a Kangaroo

我错过了一些明显的东西吗?我觉得示例 2 应该合乎逻辑地工作,但我对输出感到困惑。我猜这是一个范围问题,但我被输出“未定义”所抛弃。

ES6小提琴

2个回答

箭头函数提供了一个词法this. 它使用在this评估函数时可用的 。

它在逻辑上等同于(以下不是有效代码,因为您不能拥有名为 的变量this):

(function(this){
   // code that uses "this"
 })(this)

在您的第一个示例中,箭头函数位于构造函数中,并this指向新生成的实例。

在您的第三个示例中,没有使用箭头函数,标准this行为一如既往地工作(函数作用域中的 this)。

在你的第二个例子中,你使用了一个箭头函数,但在它评估的范围内,this是全局的/未定义的。

你可以在任何地方使用它thisthis你想的那样。例如,假设你的对象有一个setup()功能,增加了多种功能本身,你会这样称呼它:myObj.setup()该函数可以使用箭头函数来添加所需的函数。另一个更典型的用例是使用需要访问this初始上下文的回调函数
2021-03-21 14:30:04
“它使用在this评估函数时可用的那个。” 是误导。建议:“它使用this存在于创建函数的上下文中的 。” 或者甚至更好:“箭头函数根本没有自己的函数this。它们关闭this创建它们的上下文,就像关闭创建它们的变量一样。(它们也关闭arguments并且,在相关的地方,super.)”
2021-03-23 14:30:04
那么是否不能在构造函数之外将其与箭头函数一起使用(示例 2)?
2021-04-05 14:30:04
“箭头函数提供词法 this”更准确的说法是箭头函数不提供 a this,因此它不是来自其自身的词法范围,而是来自外部词法范围。
2021-04-12 14:30:04
我认为它更等同于function(){}.bind(this). 它预先绑定到this创建它的作用域的 。这在例如事件侦听器中很有帮助,我们经常希望在侦听器内部使用周围作用域中的内容。在 es5 代码中,这意味着var me = this在附加侦听器或使用bind.
2021-04-12 14:30:04

常规函数返回对当前 JavaScript 对象的引用,但箭头函数返回对全局窗口对象的引用。

常规函数可以很好地处理使用 new 关键字的对象。它们具有构造函数,通过该构造函数可以在对象创建期间初始化值。它可以使用原型链进行管理,但箭头函数没有构造函数原型链它们不能很好地处理对象。它们不能与 new 关键字一起用于分配内存。

在您的第一个示例中,您将箭头键函数写入常规函数中,然后您将获得输出。

function Animal2(name, type){
    this.name = name;
    this.type = type;
}
Animal2.prototype.toString = function(){
    return () => `${this.name} is a ${this.type}`;
}

var myPet2 = new Animal2('Noah', 'cat');
console.log(myPet2.toString()()); //Noah is a cat

参考:常规功能和方向键功能的区别