【发布时间】:2017-07-08 13:19:25
【问题描述】:
关于 SO 的第一个问题,我希望我没有重复任何内容;我看过 other questions 并认为我的与众不同足以值得询问。
基本上,有没有办法让使用速记表示法编写的方法的方法主体中的this 成为词法或绑定到特定值?
这样做的动机来自于我在实现iterator protocol 时想要使用ES6 方法简写,其中@@iterator 方法在调用时会返回一个迭代器对象。该迭代器对象必须有一个next() 方法,当调用它自己时会返回另一个对象。我希望在第二个对象中引用原始实例(在我的例子中,Graph)。
请注意,在下面的代码 sn-p 中,由于this 绑定,它没有按预期工作,next() 使用的是ES6 method definition shorthand。
class Graph {
constructor(initialNodes) {
this.data = [...initialNodes];
}
[Symbol.iterator]() {
let nextIndex = 0;
// `this` binding is fine here, as expected
return {
// look at that beautiful shorthand
next() {
return nextIndex < this.data.length
// `this` binding is not fine here
? { done: false, value: this.data[nextIndex++] }
: { done: true };
}
};
}
}
我知道在对象返回之上定义函数,然后将该函数分配为要返回的对象的属性,但我再次想知道是否可以使用方法简写语法。
将返回对象上方的next()定义为常规函数,然后在对象属性赋值中绑定:
class Graph {
// constructor
[Symbol.iterator]() {
let nextIndex = 0;
// I know you can do this
const next = function() {
return nextIndex < this.data.length
? { done: false, value: this.data[nextIndex++] }
: { done: true };
};
return {
next: next.bind(this)
};
}
}
将返回对象上方的next()定义为箭头函数意味着不需要bind,但仍然没有方法语法简写:
class Graph {
// constructor
[Symbol.iterator]() {
let nextIndex = 0;
// I know you can also do this
const next = () => {
return nextIndex < this.data.length
? { done: false, value: this.data[nextIndex++] }
: { done: true };
};
return {
next
};
}
}
Icepickle 在 cmets 中提出了一个很好的观点,我可以使用存储 this 上下文并在速记方法主体中引用它。我假设这是我能得到的最接近的?
class Graph {
// constructor
[Symbol.iterator]() {
let nextIndex = 0;
const self = this;
return {
next() {
return nextIndex < self.data.length
? { done: false, value: self.data[nextIndex++] }
: { done: true };
}
};
}
}
【问题讨论】:
-
next: () =>并不比next()长多少。我会同意的。 -
箭头语法的重点是它继承了词法
this,而不是从它的调用方式继承this。人们现在似乎只想使用箭头语法,并以某种方式使其完成原始语法所做的一切。这不是它的设计方式。如果您不打算使用词法this,那么您可能不应该使用箭头语法。使用更长的语法,然后您可以.bind()满足您的需求。 -
@jfriend00:我认为他们要求的是相反的:词法
this,但仍然使用速记方法符号。 -
@Ryan - 非常令人困惑的问题 - 只看标题。箭头语法通常不应该用于方法定义,因为您希望
this来自它被称为obj.method()的方式。我想如果不是问题标题所说的,我就不会遵循他们的要求。我在这里放弃。 -
对不起,我的问题令人困惑,@jfriend00,我不打算这样。 @Ryan 说得对,因为我想保留方法的简写但有词汇
this。我将尝试编辑我的问题以反映这一点。如果您不完全了解我来自哪里,我上面代码的问题方法是迭代器对象:当调用iterator.next()时,我希望next()中的this引用@ 987654354@ 实例。也许那是低于标准的代码,尽管我几乎是从MDN 抄来的。
标签: javascript methods ecmascript-6 this bind