TypeScript方法装饰器下派生类无法访问基类成员的问题
TypeScript方法装饰器与基类成员访问问题解答
问题成因解析
1. 派生类无法调用基类箭头函数方法base的原因
箭头函数作为类属性,会在类实例化时被赋值到实例对象本身,而非类的原型链上。你的装饰器中使用ow.call(t, props)强制将abstractFn的执行上下文绑定为装饰器的target(即Derived类的原型),而原型上不存在base这个实例属性,自然无法调用。
2. 基类属性val为undefined的原因
val是基类的实例属性,仅存在于类的实例对象中。装饰器里通过ow.call(t, props)把abstractFn的this指向了Derived的原型,原型上没有val属性,所以输出undefined。
3. 非箭头函数nonArrowFunctionBase可正常调用的原因
普通类方法会被挂载到类的原型链上,Derived的原型继承自Base的原型,所以当this指向Derived原型时,能通过原型链找到nonArrowFunctionBase方法,因此可以正常调用。
4. 装饰器target为基类原型而非实例的原因
方法装饰器是在类定义阶段执行的(而非实例化阶段),此时还没有创建类的实例。对于实例方法的装饰器,target参数对应的是类的原型对象(这里是Derived.prototype),而非实例。
修复方案
核心问题是装饰器中错误地硬绑定了this指向,应该让方法执行时的this保持为调用它的实例。修改装饰器,将箭头函数改为普通函数,并使用当前上下文的this调用原方法:
const decorator = (val: string) => { return function (t: any, pk: any, d: any) { console.log("decorator val " + val) const ow = d.value // 改为普通函数,保留调用时的this指向 d.value = function(props: any) { console.log({t, d}) console.log("decorator ", { props }) return ow.call(this, props) // 用当前this而非t } } }
修改后执行输出:
[LOG]: "decorator val world" [LOG]: { "t": {}, "d": { "writable": true, "enumerable": false, "configurable": true } } [LOG]: "decorator ", { "props": "Test" } [LOG]: "derived:abstractFn Test baseval default" [LOG]: "nonArrowFunctionBase Test" [LOG]: "base Test"
所有问题都得到解决:this.val正确获取到实例值,base箭头函数可以正常调用,nonArrowFunctionBase也保持正常工作。
内容的提问来源于stack exchange,提问作者Kaushal Bhansali
相关产品推荐
相关产品推荐

