摘要:修饰器修饰器是提出的一个提案,用来修改类的行为。目前需要才可以使用。其执行格式如下是修饰器名,即函数名相当于修饰器函数接受个参数,依次是目标函数属性名可忽略该属性的描述对象可忽略。
修饰器
修饰器是 ES7 提出的一个提案,用来修改类的行为。目前需要 babel 才可以使用。它最大的特点是:可以在编译期运行代码!其本质也就是在编译器执行的函数。其执行格式如下:
@decorator //decorator 是修饰器名,即函数名 class A{} //相当于 class A{} A = decorator(A) || A;
修饰器函数接受3个参数,依次是目标函数、属性名(可忽略)、该属性的描述对象(可忽略)。
function test(target){ target.isTestable = true; //利用修饰器给类添加静态属性 target.prototype.isTestable = true; //利用修饰器给类添加动态属性 } @test class A{} console.log(A.isTestable); //true console.log(new A().isTestable); //true
例如之前的 mixin 可以用修饰器实现一个简单的版本:
function mixins(...list){ return function(target){ Object.assign(target.prototype, ...list); } } var Foo = { foo(){console.log("foo");} }; @mixins(Foo) class Cla{} let obj = new Cla(); obj.foo(); //"foo"
修饰器不仅仅可以修饰类,还可以修饰类的属性和方法:
function readonly(target, name, descriptor){ descriptor.writable = false; return descriptor; } class Person{ constructor(name, age, tel){ this.name = name; this.id = id; } @readonly id(){return this.id}; }
当然也可以同时调用2个修饰器:
function readonly(target, name, descriptor){ descriptor.writable = false; return descriptor; } function nonenumerable(target, name, descriptor){ descriptor.enumerable = false; return descriptor; } class Person{ constructor(name, age, tel){ this.name = name; this.id = id; } @readonly @nonenumerable id(){return this.id}; }
使用修饰器应该注意:虽然类本质是个函数,但修饰器不能用于函数,因为函数具有声明提升。
core-decroators.js这是个三方模块,使用import {function Namelist} from "core-decroators";引入。它提供了几个常见的修饰器:
@autobind
是对象中的 this 始终绑定原始对象:
class Person{ @autobind whoami(){ return this; } } let person = new Person(); let getPerson = person.getPerson; getPerson() === person; //true
@readonly
使得属性方法只读
class Person{ @readonly id = gen(); //gen 是一个计数器 } var p = new Person() p.id = 123; //Cannot assign to read only property "id" of [object Object]
@override
检查子类方法是否正确的覆盖了父类的同名方法,如果不正确会报错
class Person{ work(){console.log("I am working");} } class Coder extends Person{ @override work(){console.log("I am coding");} //如果不正确会在这里报错 }
@deprecate(也作: @deprecated)
在控制台显示一条 warning,表示该方法不久后将被废除,接受一个可选的参数作为警告内容, 接受第二个参数(对象)表示更多信息
class Person{ @deprecate facepalm(){} @deprecate("We stopped facepalming") facepalmHard(){} @deprecate("We stopped facepalming", {url:"http://balabala.com"}) facepalmHarder(){} }
@suppressWarnings
抑制 deprecate 修饰器导致调用 console.warn(), 但异步代码发出的除外。
class Person{ @deprecate facepalm(){} @supressWarnings facepalmWithoutWarning(){ this.facepalm(); } } let p = new Person(); p.facepalm(); //控制台显示警告 p.facepalmWithoutWarning(); //没有警告其它第三方修饰器
此外还有一些库提供一些其他功能,比如 Postal.js(Github)中的 @publish, 可以在函数调用时发布一个事件:
import publish from "../to/decorators/publish"; class FooComponent{ @publish("foo.some.message", "component") someMethod(){} @publish("foo.some.other", "") anotherMethod(){} }
再比如 Trait(Github), 和 mixin 功能类似,提供了更强大的功能:防止同名冲突,排除混入某些方法,为混入方法起别名等
import {traits} from "traits-decorator" class TFoo{ foo(){console.log("foo1")} } class TBar{ bar(){console.log("bar")} foo(){console.log("foo2")} } @traits(TFoo, TBar) //会报错,因为这两个类中有同名方法 class MyClass{} let obj = new MyClass(); //如果没有第八行的同名方法,输出如下 obj.foo(); //"foo1" obj.bar(); //"bar"
但是我们可以修改上面第11行排除这个 foo,让它可以被覆盖:
@traits(TFoo, TBar::excludes("foo")) class MyClass{}
也可重命名同名方法:
@traits(TFoo, TBar::alias(foo:"aliasFoo")) class MyClass{}
当然绑定运算符可以链式调用:
//假设还有个同名的 baz 方法 @traits(TFoo, TBar::excludes("foo")::alias(baz:"aliasBaz")) class MyClass{} //另一种写法 @traits(TFoo, TBar::as({excludes: ["foo"], alias: {baz:"aliasBaz"}})) class MyClass{}
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97439.html
摘要:改变发布了最新版本,最新版本的模块名称都改成前缀,具体可前往英文官网查看,中文网站文档尚未更新插件包都已更换名称,以官网为准,不然会报错构造函数完全更改,一脸懵逼原先个参数改为一个对象参数,参数字段具体如下图具体查看介绍新的写法根据最 改变 babel发布了最新版本,npm最新版本的模块名称都改成@babel前缀,具体可前往babel英文官网查看,中文网站文档尚未更新 插件 plug...
摘要:装饰器是可调用的对象,其参数是另一个函数被装饰的函数。第二大特性是,装饰器在加载模块时立即执行。另一个常见的装饰器是,它的作用是协助构建行为良好的装饰器。 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数)。 装饰器基础知识 首先看一下这段代码 def deco(fn): print I am %s! % fn.__name__ @deco def func(): ...
一、前提概念 Python中的函数是对象。也因此,函数可以被当做变量使用。 二、代码模型 以下代码片段来自于: http://www.sharejs.com/codes/python/8361 # -*- coding: utf-8 -*- from threading import Thread import time class TimeoutEx...
项目地址:https://git.io/pytips Python 的修饰器是一种语法糖(Syntactic Sugar),也就是说: @decorator @wrap def func(): pass 是下面语法的一种简写: def func(): pass func = decorator(wrap(func)) 关于修饰器的两个主要问题: 修饰器用来修饰谁 谁可以作为修饰器...
阅读 1184·2021-11-17 09:33
阅读 3578·2021-09-28 09:42
阅读 3240·2021-09-13 10:35
阅读 2393·2021-09-06 15:00
阅读 2396·2021-08-27 13:12
阅读 3591·2021-07-26 23:38
阅读 1759·2019-08-30 15:55
阅读 523·2019-08-30 15:53