先看看生成器中的this:
在规范的14.4.11有这样的描述:
If the generator was invoked using [[Call]], the this binding will have already been initialized in the normal manner. If the generator was invoked using [[Construct]], the this bind is not initialized and any references to this within the FunctionBody will produce a ReferenceError exception.
我们来验证一下:
function* genFunc() {
'use strict';
yield this;
}
var [_this] = genFunc();//数组解构赋值
console.log(_this);//undefined
在试试new出来的会不会抛异常:
function* genFunc() {
'use strict';
console.log(this)
}
var g = new genFunc();
g.next();
在Chrome下并没有抛出异常,这里和规范不一样。Chrome里this就是实例g,因为this instanceof genFunc是true。
在看一下生成器是对象方法的情况:
let obj = {
*method(){yield this}
};
let [methodThis] = obj.method();
console.log(methodThis === obj); // true
class A{
*method(){
yield this;
}
}
A.prototype[Symbol.toStringTag] = "A"
class B extends A{
*method(){
let [s] = super.method();
yield s;
yield this;
}
}
B.prototype[Symbol.toStringTag] = "B"
var b = new B();
var [parent,child] = b.method();
console.log(parent.toString(),child.toString());//[object B] [object B]
var objParent = {
*method(){
yield this;
},
[Symbol.toStringTag] : "objParent"
}
var objChild = {
*method(){
var [s] = super.method();
yield s;
yield this;
},
[Symbol.toStringTag] : "objChild"
}
Object.setPrototypeOf(objChild,objParent);
var [s,t] = objChild.method();
console.log(s.toString(),t.toString());//[object objChild] [object objChild]
功能看上去是正常的,但是在规范的14.4.1中有这样的描述:
GeneratorMethod : * PropertyName ( StrictFormalParameters ) { GeneratorBody }
It is a Syntax Error if HasDirectSuper of GeneratorMethod is true
从规范上看,生成器中并不允许调用super,但是Chrome中貌似提前实现了这些语法,这也符合Google的作风,总是领先于规范。谨慎来讲,最好先不要在生成器中使用this或者super
*以上全部代码在Chrome 48中通过测试