es6 Decorator修饰器
1.类的修饰:
修饰器(Decorator)函数,用来修改类的行为。
修饰器是一个对类进行处理的函数。修饰器函数的第一个参数,就是所要修饰的目标类。
@testable
class MyTestableClass {
// ...
} function testable(target) {
target.isTestable = true;
} MyTestableClass.isTestable
上面代码中,@testable就是一个修饰器。它修改了MyTestableClass这个类的行为,为它加上了静态属性isTestable。testable函数的参数target是MyTestableClass类本身。参数target,就是会被修饰的类。
如果觉得一个参数不够用,可以在修饰器外面再封装一层函数。
function testable(isTestable) {
return function(target) {
target.isTestable = isTestable;
}
}
@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true
@testable(false)
class MyClass {}
MyClass.isTestable // false
注意,修饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。这意味着,修饰器能在编译阶段运行代码。也就是说,修饰器本质就是编译时执行的函数。
前面的例子是为类添加一个静态属性,如果想添加实例属性,可以通过目标类的prototype对象操作。
function testable(target) {
target.prototype.isTestable = true;
}
@testable
class MyTestableClass {}
let obj = new MyTestableClass();
obj.isTestable // true
上面代码中,修饰器函数testable是在目标类的prototype对象上添加属性,因此就可以在实例上调用。
实际开发中,React 与 Redux 库结合使用时,常常需要写成下面这样。
class MyReactComponent extends React.Component {}
export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);
有了装饰器,就可以改写上面的代码。
@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}
2.方法的修饰:
修饰器不仅可以修饰类,还可以修饰类的属性。
function readonly(target, name, descriptor) {
// descriptor对象原来的值如下
// {
// value: specifiedFunction, //该属性对应的值
// enumerable: false,// 为true时,才能够出现在对象的枚举属性中
// configurable: true,// 为true时,该属性描述符才能够被改变
// writable: true // 为true时,value才能被赋值运算符改变
// };
descriptor.writable = false
return descriptor
}
class Person {
@readonly
say () {
console.log("hellow!!")
}
}
let p = new Person()
p.say = function () {
console.log("你好!")
}
// 由于设置了writable=false,所以不允许修改
p.say() // hellow!!
上面代码中,修饰器readonly用来修饰“类”的name方法。
修饰器函数readonly一共可以接受三个参数。
readonly(Person.prototype, 'say', descriptor);
// 类似于
Object.defineProperty(Person.prototype, 'say', descriptor);
修饰器第一个参数是类的原型对象,上例是Person.prototype,修饰器的本意是要“修饰”类的实例,但是这个时候实例还没生成,所以只能去修饰原型(这不同于类的修饰,那种情况时target参数指的是类本身);第二个参数是所要修饰的属性名,第三个参数是该属性的描述对象。
另外,上面代码说明,修饰器(readonly)会修改属性的描述对象(descriptor),然后被修改的描述对象再用来定义属性。
修饰器传参(用法同类的修饰器,可以在修饰器外面再封装一层函数):
function dec(id){
console.log('evaluated', id);
return (target, property, descriptor) => console.log('executed', id);
}
class Example {
@dec(1)
@dec(2)
method(){}
}
// evaluated 1
// evaluated 2
// executed 2
// executed 1
如果同一个方法有多个修饰器,会像剥洋葱一样,先从外到内进入,然后由内向外执行。上面代码中,外层修饰器@dec(1)先进入,但是内层修饰器@dec(2)先执行。
修饰器只能用于类和类的方法,不能用于函数,因为存在函数提升(如果一定要修饰函数,可以采用高阶函数的形式直接执行。)
借鉴阮一峰的Es6教程:http://es6.ruanyifeng.com/#docs/decorator
es6 Decorator修饰器的更多相关文章
- ES6(Decorator(修饰器))
Decorator(修饰器) 1.基本概念 函数用来修改 类 的行为 1.Decorator 是一个函数 2.通过Decorator(修饰器)能修改 类 的行为(扩展 类 的功能)3.Decorato ...
- ES6 Decorator 修饰器
目的: 修改类的一种方法,修饰器是一个函数 编译: 安装 babel-plugin-transform-decortators-legacy .babelrd plugins: [&quo ...
- 19.Decorator修饰器
Decorator 修饰器 类的修饰 许多面向对象的语言都有修饰器(Decorator)函数,用来修改类的行为.目前,有一个提案将这项功能,引入了 ECMAScript. @testable clas ...
- mobx中使用class语法或decorator修饰器时报错
之前课程中老师用的babel的版本比较低,我在学习时安装的babel版本较高,因此每当使用class语法或decorator修饰器时都会出现一些报错的情况! ❌ ERROR in ./src/inde ...
- js基石之---es7的decorator修饰器
es7的decorator修饰器 装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法. decorator就是给类添加或修改类的变量与方法的. 装饰器是一种函数, ...
- python decorator 修饰器
decorator 就是给函数加一层皮,好用! 1 from time import ctime 2 3 def deco(func): 4 def wrappedFunc(*args, **kwar ...
- 21.Decorator修饰器
1.类的修饰 2.方法的修饰 3.为什么修饰器不能用于函数? 4.core-decorators.js 5.使用修饰器实现自动发布事件 6.Mixin 7.Trait 8.Babel转码器的支持
- mobx学习笔记03——mobx基础语法(decorator修饰器)
在声明阶段实现类与类成员注解的一种语法. function log(target){ const desc = Object.getOwnPropertyDescriotors(target.prot ...
- ES6里的修饰器Decorator
修饰器(Decorator)是一个函数,用来修改类的行为. 一.概述 ES6 引入了这项功能,目前 Babel 转码器已经支持Decorator 首先,安装babel-core和babel-plugi ...
随机推荐
- WPF ObservableCollection,INotifyPropertyChanged
xaml: <DockPanel Margin="10"> <StackPanel DockPanel.Dock="Rig ...
- IdentityService4学习笔记之Authorization Code
前文 本文所有内容来自官方文档,如果有写不明白的地方请下方留言或查看官方文档. 今天介绍Authorization Code模式,适用于保密类型的客户端,保密类型客户端可以理解为在服务器端生成页面(比 ...
- git 命令从入门到放弃
o(︶︿︶)o 由于项目使用 git 作为版本控制工具,自己可以进行一些常用操作但是有时候还是会忘掉,导致每次遇到 git 命令的使用问题时就要再查一遍,效率就立马降下来了,所以今天就来一个从头到尾 ...
- Laravel处理session(会话)的方法详解
在Web应用程序中,有必要识别跨越请求的用户并为每个用户保存数据,为此,像Laravel这样的框架提供了一种称为会话的机制.本篇文章就来为大家介绍关于Laravel处理session(会话)的方法. ...
- unity点击按钮弹出操作提示界面
1.首先在相应的位置添加一个(UGUI控件)image,在image下添加文本框和按钮设计弹出框内容如图: 2.新建C#脚本UITips using System.Collections; using ...
- MySQL truncate含有外键约束的条目报错
1.报错信息: Cannot truncate a table referenced in a foreign key constraint 2.出现错误操作: truncate table a1; ...
- django framework插件使用1
安装 REST框架要求以下内容: Python(3.5.3.6.3.7) Django(1.11.2.0.2.1.2.2) pip install djangorestframework pip in ...
- Linux系统运行模式介绍
Linux运行模式 自由服务,即不需要用户独立去安装的软件服务,而是在系统安装好之后就可以直接使用的服务(内置服务). 运行模式也称为运行级别,属于linux的自有服务. 运行模式可以理解为一旦你开机 ...
- mysql系列2 权限相关
mysql授权认证 请注意(大坑):mysql8.0以前的版本可以使用grant在授权的时候隐式的创建用户,8.0以后已经不支持,所以必须先创建用户,然后再授权!! 例子: 在170mysql主机上授 ...
- javascript打开窗口
项目中javascript代码,早期使用了只有ie支持的方法:Window createPopup() 方法 那个时候是2009年,而现在已经是2019-12-11了.如何改造这个早期的代码呢? 找到 ...