首页 > 专栏 > 前端 > 文章详情
Generator 函数的 this 问题和 new 使用 发布于:2021-03-12 15:58:18   来源:阮一峰   查看:4  讨论:0
示例Genertor函数:
function* g() {};
g.prototype.hello = function () {
    return 'Hi';
}
let obj = g();
console.log(obj instanceof g);//true
console.log(obj.hello());//Hi

obj是g的实例,而且继承了g.prototype。但是,如果把g当做普通函数,不生效,因为g返回遍历器对象,不返回this对象。Gkm易塔云建站-模板下载,web开发资源,技术博客

function* g() {
    this.a = 11;
};
let obj = g();
console.log(obj.a);//undefined
上面,Genertor函数g在this对象上添加了一个属性,但是obj对象拿不到这个属性。Gkm易塔云建站-模板下载,web开发资源,技术博客
Genertor函数也不能使用new命令。
function* F() {
    yield this.x = 2;
    yield this.y = 3;
};
new F();//F is not a constructor
上面,因为F不是构造函数。如何,既可以用next方法,也可以获得正常this值:
/*通过一种方法,是Genertor函数具有this值功能*/
function * F(){
    this.a = 1;
    yield this.b = 2;
    yield this.c = 3;
}
var it = F();
var obj = {};
var f = F.call(obj);//把obj当做参数,来调用F()的方法。
console.log(f)

console.log(it.next());//{value:2, done:false}
console.log(it.next());//{value:3, done:false}
console.log(it.next());//{value:undefined, done:true}

console.log(f.next());//{value:2, done:false}
console.log(f.next());//{value:3, done:false}
console.log(f.next());//{value:undefined, done:true}

console.log(it.a);//undefined 因为generator函数总是返回一个遍历器对象
console.log(obj.a);//1
console.log(obj.b);//2
console.log(obj.c);//3 可以正常获取
上面,使用call方法绑定Genertor函数内部的this。调用构造函数后,此空对象 是 Genertor函数的实例。Gkm易塔云建站-模板下载,web开发资源,技术博客
上面,首先是F内部的this对象绑定obj对象,然后调用它,返回一个Iterator对象。对象执行3此next方法(因为F内部有两个yield表达式),完成F内部所有代码的运行。这时,所有内部属性都绑定在obj对象上了,因此obj对象也就成了F的实例。Gkm易塔云建站-模板下载,web开发资源,技术博客
上面的代码执行的是遍历器对象F,但是生产的对象实例是obj,有没有办法统一:Gkm易塔云建站-模板下载,web开发资源,技术博客
    □:一个办法就是将obj换成F.prototype。
/*解决上面的函数不统一问题*/
// var f = F.call(F.prototype);//将obj换成F.prototype
//此时能使用f.next()直接取到 每一步骤的值
//也可以使用f.a获取属性值
    □:再将F改成构造函数,就可以使用new命令。
/*再将F改造成构造函数,就可以使用new命令了*/
function* gen() {
    this.a =1;
    yield this.b = 2;
    yield this.c = 3;
}
function F() {
    return gen.call(gen.prototype);//这句话 等同于 F.call(F.prototype),只不过现在当做一条返回值,装在了构造函数里
    //让构造函数F成立,下面才能用到new。
    //不要被函数的外表所迷惑,重要的是函数传递逻辑。
}
var f = new F();
console.log(f.next());
console.log(f.next());
console.log(f.next());
console.log(f.a);
console.log(f.b);
console.log(f.c);

评论

  • 匿名