我正在尝试确定允许用户将类的方法传递到promise链中的最佳方式。目前,代码看起来是这样的,我得到了预期的错误。
class Parent {
async say(word) {
console.log(word);
}
}
class MyClass extends Parent {
async start() {
console.log("OK, starting");
return "starting";
}
async doThis(something) {
this.say(something);
}
}
async function boot() {
const cl = new MyClass();
await cl.start().then(cl.doThis); <-- Scoping issue
}
boot();
// Output
OK, starting
code.js:16
this.say(something);
^
TypeError: Cannot read properties of undefined (reading 'say')
at doThis (code.js:16:8)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async boot (code.js:22:2)
我完全预料到会出现这种错误,因为(据我所知(当我将cl.doThis
作为解析链的一部分传递时,我实际上是在传递函数本身,而this
正在被重新绑定。如果我在这个假设上错了,请纠正我,但我再次认为这会失败。
我的反应是更改为适当的函数,以便保持适当的绑定:
async function boot() {
const cl = new MyClass();
await cl.start().then(response => cl.doThis(response));
}
不过,当我调用父函数时,它告诉我使用super
而不是this
。
class MyClass extends Parent {
// ...
async doThis(something) {
super.say(something);
}
}
这只是避免了错误,因为我们不再使用this
,总是调用super.<method>()
并最终不得不跟踪从父类调用哪些方法似乎非常困难(如果一个子类覆盖父类,这将被忽略,现在我有一些类调用super
,而另一些类使用this
(。
有没有更好的方法来解决这个问题,或者只说你需要将类方法调用封装在一个合适的函数中以保持作用域?
我被告知在调用时使用
super
而不是this
父函数:class MyClass extends Parent { async doThis(something) { super.say(something); } } async function boot() { const cl = new MyClass(); Promise.resolve().then(cl.doThis); }
同时避免了
this
为undefined
的错误,…
不,它不起作用。this
的结合仍然是undefined
。唯一的区别是您不再使用它,无论是在doThis
还是在say
中。但是,如果在父方法中执行了console.log(this, word)
,您就会意识到它实际上是undefined
。这是因为super.say(something)
只是的语法糖
Object.getPrototypeOf(MyClass.prototype).say.call(this, something);
将方法作为回调传递的正确方法仍然是使用.bind()
或箭头函数。