es7 class装饰器
文档http://es6.ruanyifeng.com/#docs/decorator
ts文档 https://www.tslang.cn/docs/handbook/decorators.html#class-decorators
当多个装饰器应用于一个声明上,从上至下调用,从下而上执行
function info(opt: {
username: string;
age: number;
email: string;
}) {
return function (klass: any) {
klass.username = opt.username;
klass.age = opt.age;
klass.email = opt.email;
}
}
@info({
username: 'ajanuw',
age: 14,
email: '123@sina.com'
})
class Ajanuw {
constructor() { }
}
const klass = (<any>Ajanuw);
console.log(klass.username, klass.age, klass.email);
es 的装饰器
let l = console.log
function klass(value) {
return target => {
// l(value) // api
// l(target) // 对象
}
}
function prop(value) {
return function (target, key, des) { // target 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
// l(value) // username
// l(target, key, des) // 对象,属性名,属性描述符
}
}
function func(value) {
return function (target, key, des) { // target 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
// l(value) // function
// l(key) // 函数名 show
// l(des.value) // show函数, 可以改写
// des.value = function(){
// l('hello')
// }
}
}
function Body(target) {
// l( target ) // undefined
}
@klass('api')
class Ajanuw {
@prop('username') name = 'ajanuw'
@func('function')
show(@Body body) {
l(body)
}
}
new Ajanuw().show()
重载构造函数
function classDecorator<T extends { new (...args: any[]): {} }>(
constructor: T
) {
return class extends constructor {
newProperty = "new property";
hello = "override";
};
}
@classDecorator
class Greeter {
constructor(public hello: string) {}
}
var g = new Greeter("world");
console.log(g.hello); // override
参数装饰器
import "reflect-metadata";
const requiredMetadataKey = Symbol("required");
const bodyMetadataKey = Symbol("body");
function required(
target: Object,
propertyKey: string | symbol,
parameterIndex: number
) {
let existingRequiredParameters: number[] =
Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || [];
existingRequiredParameters.push(parameterIndex);
Reflect.defineMetadata(
requiredMetadataKey,
existingRequiredParameters,
target,
propertyKey
);
}
function Body(key: string): any {
return function (target: any, propertyKey: string, parameterIndex: number) {
let existingRequiredParameters: any[] =
Reflect.getOwnMetadata(bodyMetadataKey, target, propertyKey) || [];
existingRequiredParameters.push({ parameterIndex, key });
// 注入元数据
Reflect.defineMetadata(
bodyMetadataKey,
existingRequiredParameters,
target,
propertyKey
);
};
}
function validate(
target: any,
propertyName: string,
descriptor: TypedPropertyDescriptor<any>
) {
let method = descriptor.value;
// 重写value
descriptor.value = function () {
let requiredParameters: number[] = Reflect.getOwnMetadata(
requiredMetadataKey,
target,
propertyName
);
if (requiredParameters) {
for (let parameterIndex of requiredParameters) {
if (
parameterIndex >= arguments.length ||
arguments[parameterIndex] === undefined
) {
throw new Error("Missing required argument.");
}
}
}
// 获取目标对象上提供的元数据键的元数据值
Reflect.getOwnMetadata(bodyMetadataKey, target, propertyName)?.forEach(
(it: any) => {
// 重写参数
arguments[it.parameterIndex] = arguments[it.parameterIndex][it.key];
}
);
return method?.apply(this, arguments);
};
}
class Greeter {
@validate
greet(@required @Body("name") name: any): any {
console.log("Hello " + name); // Hello xxxx
}
}
const g = new Greeter();
g.greet({ name: "xxxx" });
es7 class装饰器的更多相关文章
- 装饰器模式&&ES7 Decorator 装饰器
装饰器模式(Decorator Pattern)允许向一个现有的对象动态添加新的功能,同时又不改变其结构.相比JavaScript中通过鸡肋的继承来给对象增加功能来说,装饰器模式相比生成子类更为灵活. ...
- koa2使用es7 的装饰器decorator
本文主要讲述我在做项目中使用装饰器(decorator)来动态加载koa-router的路由的一个基础架构. 目前JavaScript 对decorator 是不支持,但是可以用babel 来编译 既 ...
- JS 装饰器,一篇就够
更多文章,请在Github blog查看 在 ES6 中增加了对类对象的相关定义和操作(比如 class 和 extends ),这就使得我们在多个不同类之间共享或者扩展一些方法或者行为的时候,变得并 ...
- 简单理解 ES7 Decorator(装饰器)
如何使用ES7 Decorator给你的游戏人物开挂? // 预告: 本文有点小难度,对js不太熟的人可能比较懵逼 // 本文的目的是让你们知其然 // ======================= ...
- 在express中使用ES7装饰器构建路由
在Java的Spring框架中,我们经常会看到类似于@Controller这样的注解,这类代码能够极大的提高我们代码的可读性和复用性.而在Javascript的ES7提案中,有一种新的语法叫做deco ...
- 从C#到TypeScript - 装饰器
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- Javascript 装饰器极速指南
pablo.png Decorators 是ES7中添加的JavaScript新特性.熟悉Typescript的同学应该更早的接触到这个特性,TypeScript早些时候已经支持Decorators的 ...
- 【Angular专题】 (3)装饰器decorator,一块语法糖
目录 一. Decorator装饰器 二. Typescript中的装饰器 2.1 类装饰器 2.2 方法装饰器 2.3 访问器装饰器 2.4 属性装饰器 2.5 参数装饰器 三. 用ES5代码模拟装 ...
- MobX基础 ----- 类的静态属性和装饰器
当我们使用MobX的时候,首先要声明一个store, 用来保存状态,它的最基本的语法 如下: class Todo { @observable title = ""; @obser ...
随机推荐
- 本地项目文件夹同步到GitLab的操作步骤
一.需求 本地有一个微信小程序的项目源码,只是文件夹的形式,包括一些js和一些页面,想把这个文件夹用GitLab管理,于是就需要把本地文件夹push到服务器的GitLab上面 二.操作 2.1:本地文 ...
- C# System.Collections.ArrayList
using System; using System.Collections; public class SamplesArrayList { public static void Main() { ...
- asp.net core 2.1 post 无法提交参数?
起 ,是微软二逼升级了.....不是说好了合并Controller 了吗?又倒回去了.................
- Variable used in lambda expression should be final or effectively final
Lambda与匿名内部类在访问外部变量时,都不允许有修改变量的倾向,即若: final double a = 3.141592; double b = 3.141592; DoubleUnaryOpe ...
- 11G新特性 -- variable size extents
AU是asm磁盘分配的基本单元.在oracle10g中,一个AU对应一个extent(这会增加对内存的使用),因为一个大的数据库如果含有大量的默认大小的AU,会导致数据库的share pool的大量使 ...
- html中<a>标签的种类
在html中a 标签是一个链接标签,然而a 标签也有非常多的种类,在此做一个小结. 一.普通链接 <a href="http://www.baidu.com">百度&l ...
- 深入理解Fsync
1 介绍 数据库系统从诞生那天开始,就面对一个很棘手的问题,fsync的性能问题.组提交(group commit)就是为了解决fsync的问题.最近,遇到一个业务反映MySQL创建分区表很慢,仔细分 ...
- 各种软件的安装教程centos mysql tomcat nginx jenkins jira 等等
464 Star3,606 Fork 1,460 judasn/Linux-Tutorial 作者: https://github.com/judasn Linux-Tutorial/markdow ...
- SNF快速开发平台MVC-表格单元格合并组件
1. 表格单元格合并组件 1.1. 效果展示 1.1.1. 页面展现表格合并单元格 图 4.1 1.1.2. 导出excel合并单元格 图 4.2 1.2. 调用说 ...
- [svc]linux的ip命令操作接口和路由表
参考: https://www.tecmint.com/ip-command-examples/ 学会linux的配置ip,配置网关,添加路由等命令 man ip man ip address man ...