我尝试覆盖/代理库类中的函数。我通过扩展类并在方法上定义一个
Proxy
对象来完成此操作。
唉,就像这个问题一样,派生类中的
this
对象是未定义的。我似乎无法让“那些解决方案”在我的案例中发挥作用。也许是由于使用了Proxy
。参见下面的示例:
class Structure {
constructor (name){
this.noDoors = 0
this.name = name
}
async addDoors(noDoorsToAdd){
this.noDoors += noDoorsToAdd
console.log(`${noDoorsToAdd} doors added to ${this.name}`)
return new Promise(r=>r())
}
}
const Building = class Building extends Structure {
constructor(conditionfunc,args){
super(args)
this.addDoors = new Proxy(this.addDoors, {
apply(target, thisArg, argumentsList){
//console.log("apply:",target, thisArg, argumentsList,conditionfunc(argumentsList[0]))
if (conditionfunc(argumentsList[0])){
console.log(`Correct password: About to add doors to ${thisArg.name}`)
target(argumentsList[1]);
}
else {
console.log(`Incorrect password: Doors not added to ${thisArg.name}`)
}
}
})
}
}
/******** Main Script *********/
let conditionfunc = (password) => {
if (password == '123456') { return true } else {return false }
}
myStructure = new Structure('Ty Bach')
myBuilding = new Building(conditionfunc,'Ty Mawr')
;(async()=>{
await myStructure.addDoors(1)
await myBuilding.addDoors('wrongpassword',7)
await myBuilding.addDoors('123456',4)
console.log(`${myStructure.name} has ${myStructure.noDoors} doors!`)
console.log(`${myBuilding.name} has ${myBuilding.noDoors} doors!`)
})();
在这里,我期望
myBuilding
对象最终有 4 扇门。
我的控制台上的错误消息是:1 doors added to Ty Bach
Doors not added to Ty Mawr
About to add doors to Ty Mawr
Ty Bach has 1 doors!
Ty Mawr has 0 doors!
(node:3732) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'noDoors' of undefined
at addDoors (MYPATH\proxytoy\test.js:11:3)
at Object.apply (MYPATH\proxytoy\test.js:26:6)
at MYPATH\proxytoy\test.js:51:23
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3732) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:3732) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
this
未定义?
this
。
使用target.call(thisArg, argumentsList[1])
代替
class Structure {
constructor(name) {
this.noDoors = 0
this.name = name
}
async addDoors(noDoorsToAdd) {
this.noDoors += noDoorsToAdd
console.log(`${noDoorsToAdd} doors added to ${this.name}`)
return new Promise(r => r())
}
}
const Building = class Building extends Structure {
constructor(conditionfunc, args) {
super(args)
this.addDoors = new Proxy(this.addDoors, {
apply(target, thisArg, argumentsList) {
//console.log("apply:",target, thisArg, argumentsList,conditionfunc(argumentsList[0]))
if (conditionfunc(argumentsList[0])) {
console.log(`Correct password: About to add doors to ${thisArg.name}`)
target.call(thisArg, argumentsList[1]);
} else {
console.log(`Incorrect password: Doors not added to ${thisArg.name}`)
}
}
})
}
}
/******** Main Script *********/
let conditionfunc = (password) => {
if (password == '123456') {
return true
} else {
return false
}
}
myStructure = new Structure('Ty Bach')
myBuilding = new Building(conditionfunc, 'Ty Mawr')
;
(async() => {
await myStructure.addDoors(1)
await myBuilding.addDoors('wrongpassword', 7)
await myBuilding.addDoors('123456', 4)
console.log(`${myStructure.name} has ${myStructure.noDoors} doors!`)
console.log(`${myBuilding.name} has ${myBuilding.noDoors} doors!`)
})();