超级厉害的JavaScript —— ECMAScript 6 标准(11) —— Decorator

什么是Decorator

Decorator是修饰器,用来修饰类的行为,它是ES7的一个实现,目前Babel转码器已经支持。


修饰器的使用

修饰器对类的行为的改变,是发生在代码编译时的。修饰器也只能对类以及类的属性使用。

修饰类

function testable(target) {
  target.isTestable = true;
}

@testable
class MyTestableClass {}

console.log(MyTestableClass.isTestable) // true

最简化来看:

@decorator
class A {}

// 等同于以下行为

class A {}
A = decorator(A) || A;

也就是说,修饰器本质就是编译时对target执行的函数。
类修饰器的第一个参数target,就是要修饰的目标类。同时,因为修饰器只是函数,所以可以使用执行的函数,而不是函数指针,只要最后有一个接受target的函数修饰类就可以了:

function testable(isTestable) {
  return function(target) {
    target.isTestable = isTestable;
  }
}

@testable(true) //执行testable后是返回函数指针
class MyTestableClass {}
MyTestableClass.isTestable // true

@testable(false)    
class MyClass {}
MyClass.isTestable // false

现在都是添加静态属性,如果想添加实例属性,就只能添加到target的原型(prototype)上了:

function testable(target) {
  target.prototype.isTestable = true;
}

@testable
class MyTestableClass {}

let obj = new MyTestableClass();
obj.isTestable // true

这里会有个问题!!!!!!!!

修饰属性

修饰属性时修饰函数一共接受三个参数,第一个参数是所要修饰的目标对象(ClassName.prototype),第二个参数是所要修饰的属性,第三个参数是该属性的描述对象,还有一点,修饰属性时需要返回描述对象:

function readonly(target, name, descriptor){
    descriptor.writable = false;
    return descriptor;
}

class Person {
    @readonly
    name() { return "Person" }
}

以上Person实例的name方法就是只读的了。

value的修改可以实现输出日志的作用:

class Math {
  @log
  add(a, b) {
    return a + b;
  }
}

function log(target, name, descriptor) {
  var oldValue = descriptor.value;   //暂存了原来的方法

  descriptor.value = function() {   //使用新的方法
    console.log(`Calling "${name}" with`, arguments);
    return oldValue.apply(null, arguments); //最后再调用旧方法获得执行的结果
  };

  return descriptor;
}

const math = new Math();

// passed parameters should get logged now
math.add(2, 4);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值