看看这个类,Base 和 Derived,它们只是具有“名称”作为属性的简单类:
class Base {
constructor(name) {
this.name = name;
}
printName() {
console.log("Base: " + this.name);
}
}
class Derieved extends Base {
constructor(name) {
super(name);
}
// Override
printName() {
// IIFE.
(function() {
super.printName(); // Can't use super here
})();
console.log("Derived: " + this.name);
}
}
var obj = new Derieved('John');
obj.printName();
我想从 Derieved::printName 调用 Base::printName。但出于某种原因,我必须调用 Derieved::printName 的内部函数内部。
但是运行上面的代码,它失败了:
SyntaxError: 'super' keyword unexpected here
如果我将父方法的引用保存到变量中,看起来它可以调用但无法访问任何属性,它说未定义。
TypeError: Cannot read property 'name' of undefined
我刚刚写了内部函数只是普通函数,但实际上它是生成器函数,所以我不能使用箭头函数:
get(match: T, options: IQueryOptions|void): Promise<Array<Object>|Error> {
const superGet = super.get;
return new Promise((resolve, reject) => {
co(function*() {
try {
// I need to invoke parent's get method here!!
const accounts = yield superGet(match, options);
... // do something with accounts
resolve(accounts);
}
catch(err) {
...
}
});
});
}
有办法做到这一点吗?为什么我无法将父方法的引用保存到变量中?
最佳答案
super
只能从子方法访问,而不能从该方法内部调用的函数范围访问。
生成器函数仍然是函数并且支持绑定(bind)。这将导致绑定(bind)函数无法通过其签名识别为生成器函数,但只要协程库支持通用迭代器( co
),那就没问题。
所以基本上是这样的
get(...) {
const superGet = super.get;
return new Promise((resolve, reject) => {
co(function*() {
...
const accounts = yield superGet.call(this, match, options);
...
}.bind(this));
});
}
或者更好:
get(...) {
const superGet = super.get.bind(this);
return new Promise((resolve, reject) => {
co(function*() {
...
const accounts = yield superGet(match, options);
...
});
});
}
这里有几件事可以改进。第一个是它使用 Promise 构造函数反模式。 co
已经返回了一个 Promise,无需用 new Promise
包装它。
另一件事是,为了无缝继承,将生成器方法和 promise 方法分开是有益的。 co
支持委托(delegate)yield
,它使这变得更加容易:
class Base {
get(...args) {
return co(this._get.bind(this, ...args));
}
* _get(...) { ... }
}
class Child extends Base {
* _get(...) {
...
const accounts = yield* super._get(match, options);
...
}
}
TypeScript 和 Babel 都支持 ES2017 async..await
,并且能够在 ES6 目标输出中回退到类似 co
的生成器协程。这使得 co
在转译的 JS 项目中毫无用处,上面的代码变成:
class Child extends Base {
async get(...) {
...
const accounts = await super.get(match, options);
...
}
}
关于javascript - 如何访问内部生成器函数内部的父类(super class)方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46683552/