十一、装饰器

218 阅读1分钟

在用angular-cli脚手架工具创建项目的时候,经常能看到以下代码

@Component({
	selector: "thingy",
	template: `foo`
})
class MyComponent {
}

装饰器是typescript中的一个特性,当然它也可能会被以后的es版本中纳入,但是在现行的版本中,es6都还不具备这个特性
它允许我们装饰类和函数,它其实概念非常简单,而装饰器其实本质上也就是个高阶函数

无参装饰器

下面将通过一个person的类创建一个名为@course的装饰器来解释

@course
class Person {
    firstName;
    lastName;

    constructor(firstName, lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

@course,其实是一个函数,可以理解为类似这样的:

function course(target) {
    Object.defineProperty(target.prototype, 'course', {value: () => "Angular 6"})
}

course的参数target,是装饰器所附加的,所以一个类的底层实现就是一个类将会成为这个类的构造函数
所以我们可以通过Object.defineProperty动态添加一个函数到course中
所以我们可以用course方法,然后打印出Angular 6

let asim = new Person("Asim", "Hussain");
console.log(asim.course()); // Angular 6

带参装饰器

但是我们如何将参数传递给我们的decorator,就像@component装饰器一样?
我们可以创建一个函数返回一个装饰器

function Student(config) { // 1
  return function (target) {
    Object.defineProperty(
        target.prototype,
        'course',
        {value: () => config.course} // 2
    )
  }
}

我们通过一个config对象传递course方法,然后在返回的内部装饰函数中使用config,然后可以写成

@Student({
    course: "Angular 2"
})
class Person {
}

总结

其实装饰器就是个高阶函数,他是typescript的一个特性,在angular的项目中大象使用,有了装饰器可以更方便的设计类
它只是可以用来将元数据、属性或函数添加到它们所依附的东西上。