许多面向对象都有decorator(装饰器)函数,比如python中也可以用decorator函数来强化代码,decorator相当于一个高阶函数,接收一个函数,返回一个被装饰后的函数。
注: javascript中也有decorator相关的提案,只是目前node以及各浏览器中均不支持。只能通过安装babel插件来转换代码,插件名叫这个:transform-decorators-legacy。也有在线试用](https://babeljs.io/repl/),安装好transform-decorators-legacy之后,就能看到转义后的代码了:
npm i -D @babel/plugin-proposal--decorators
可以再下载一个plugin配置类里面属性的写法
npm i -D @babel/plugin-proposal-class-properties
在babelrc中配置插件:
2.1 使用decorator的前期配置
1.vscode里面去除装饰器报错的方法
在vscode里打开设置=>用户设置里面加入(tips:打开设置后也可以直接点击右上角的'{}'进行用户设置)
就可以了。
2.搭建一个简单的webpack 来使用装饰器
由于目前浏览器和node暂时不支持装饰器,所以我们可以配置一个webpack来使用装饰器
全局安装:
启动配置 创建一个webpack.dev.js
下载依赖(webpack4.x 方法 )
npm install -D babel-loader @babel/core @babel/preset-env
配置.babelrc
创建好webpack的目录结构是这样的
package.json的配置
2.2 开始使用decorator
1.类的修饰
许多面向对象的语言都有修饰器(Decorator)函数,用来修改类的行为。目前,有一个提案将这项功能,引入了 ECMAScript。 下面我们采用一个钢铁侠的例子来展开
上面代码中,@transform就是一个修饰器。它修改了IronMan这个类的行为,为它加上了武器属性weapon。transform函数的参数target是IronMan类本身。
2.方法的修饰
修饰器不仅可以修饰类,还可以修饰类的属性。
上面代码中,修饰器readonly用来修饰“类”的name方法。
修饰器函数readonly一共可以接受三个参数。
修饰器第一个参数是类的原型对象,上例是Person.prototype,修饰器的本意是要“修饰”类的实例,但是这个时候实例还没生成,所以只能去修饰原型(这不同于类的修饰,那种情况时target参数指的是类本身);第二个参数是所要修饰的属性名,第三个参数是该属性的描述对象。
4.装饰器不能用于修饰函数
原本作者设计的时候 是可以使用这种方式的 比如修饰一个函数这么写
这意味着装饰器可以用于任何任务,但是作者认为这样可能有点复杂 并且还有一个潜在的问题 装饰器和跟随变量一块提升 使得装饰器语法函数过早执行而导致因为位置的原因产生的一些错误 比如:
总而言之,作者不希望产生这样的复杂性,所以去除了修饰函数,详情可以参考这篇作者参与讨论的帖子
5.应用
至于decorator的应用场景在哪里?应该大部分AOP的场景都可以用,例如日志系统。 这里就手动来实现一个简单的日志系统。
6.core-decorators.js
core-decorators.js是一个第三方模块,提供了几个常见的修饰器,通过它可以更好地理解修饰器。
(1)@readonly
readonly修饰器使得属性或方法不可写。
(2)@override
override修饰器检查子类的方法,是否正确覆盖了父类的同名方法,如果不正确会报错。
(3)@deprecate (别名@deprecated)
deprecate或deprecated修饰器在控制台显示一条警告,表示该方法将废除。