看看这个类,Base和Derived,它只是将“name”作为属性的简单类:
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'关键字在这里意外
如果我将父方法的引用保存到变量,看起来它可以调用但不能访问任何属性,它说未定义。
TypeError:无法读取未定义的属性“name”
我刚写的内部函数只是普通函数,但实际上它是生成函数,所以我不能使用箭头函数:
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) {
...
}
});
});
}
有没有办法解决这个问题?为什么我不能将父方法的引用保存到变量中?
答案 0 :(得分:2)
super
只能从子方法访问,而不能从此方法中调用的函数范围访问。
生成器功能仍然是功能并支持绑定。这将导致绑定函数无法通过其签名识别为生成器函数,但只要协程库支持泛型迭代器(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构造函数antipattern。 co
已经返回一个承诺,没有必要用new Promise
包装它。
另一方面,为了无缝继承,分离生成器方法和promisified方法是有益的。 co
支持委派的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
,并且能够回退到co
- 就像ES6目标输出中的生成器协同程序一样。这使co
在已编译的JS项目中无效,上面的代码变为:
class Child extends Base {
async get(...) {
...
const accounts = await super.get(match, options);
...
}
}
答案 1 :(得分:1)
显然,无论如何你都会为类型注释使用一些编译器。在这种情况下,解决方案是删除href="javascript:void(0)"
库和生成器,并使用适当的现代d[order(as.Date(d$V3, format="%d/%m/%Y)),]
/ co
语法,TypeScript,Babel和native nodejs支持:< / p>
async
await
将在此处开箱即用。
答案 2 :(得分:0)
箭头有助于救援!
class Base {
constructor(name) {
this.name = name;
}
printName() {
console.log("Base: " + this.name);
}
}
class Derieved extends Base {
constructor(name) {
super(name);
}
// Override
printName() {
// IIFE
(() => {
super.printName(); // Can't use super here
})();
console.log("Derived: " + this.name);
}
}
var obj = new Derieved('John');
obj.printName();
基本上,箭头函数维护this
和super
上下文,与文字function
关键字