【问题标题】:How decorator run I get a error when I use it装饰器如何运行我使用它时出错
【发布时间】:2017-07-18 23:01:05
【问题描述】:

我在我的项目中使用过 webpack 和 babel 来使用装饰器,当我像下面这样写时:

class Man{
    constructor(weight = 10, height = 10){
        this.init(weight, height);
    }
    @decorateWeight
    init(w, h){
        this.weight = w;
        this.height = h;
    }
    toString(){
        return `weight: ${this.weight}, height:${this.height}`;
    }
}

function decorateWeight(target, key, descriptor){
    const method = descriptor.value;
    let moreWeight = 100;
    let ret;
    descriptor.value = (...args) => {
        args[0] += moreWeight;
        ret = method.apply(target, args);
        return ret;
    }
    return descriptor
}

它似乎工作正常,但是当我在下面添加这样一行时:

class Man{
    constructor(weight = 10, height = 10){
        this.date = new Date();
        this.init(weight, height);
    }
    @decorateWeight
    init(w, h){
        this.weight = w;
        this.height = h;
        console.log(this.date.getTime());
    }
    toString(){
        return `weight: ${this.weight}, height:${this.height}`;
    }
}

当我新建一个 Man 实例时,出现“无法调用未定义的 'getTime'”的错误,我不明白,我在哪里出错了?

【问题讨论】:

  • 它只是用于像这样的不确定参数:function fn2(...args){return args.reduce(function(x,y){return x + y})};fn2(1 ,2,3,4,5);
  • 装饰器不是 ES7 (ES2016) 的一部分。这是一个实验性功能!
  • 谢谢提及。我对此有点困惑。

标签: javascript decorator ecmascript-next


【解决方案1】:

您的问题是method.apply(target, … 行和箭头函数的使用。装饰器的targetMan.prototype,而不是实例。即使是您的第一个 sn-p 也不会像您认为的那样做(您可以在实例化多个对象时看到它)。

相反,您应该为该方法使用function,并在引用实例的当前this 值上调用原始method

function decorateWeight(target, key, descriptor){
    const method = descriptor.value;
    const moreWeight = 100;
    descriptor.value = function (...args) {
        args[0] += moreWeight;
        return method.apply(this, args);
    };
    return descriptor;
}

【讨论】:

  • 谢谢,它有效。我真的误会了。
猜你喜欢
  • 1970-01-01
  • 2022-11-29
  • 2010-09-25
  • 2019-08-22
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2021-07-19
相关资源
最近更新 更多