从C#到TypeScript - Reflect
总目录
从C#到TypeScript - Reflect
在C#里如果想只通过名字来生成类实例、获取属性或执行方法可以使用反射,反射是基于元数据,现在很多流行语言都支持元数据,以此来提供更多便利的功能。
ES6和TypeScript也有Reflect,不过因为JavaScript本身是解释型语言,很多操作如根据名字字符串获取属性,根据字符串执行函数这些原本就有支持,Reflect只是把这些操作归结到一起。
下面来通过例子来看下TS Reflect常见的用法。
Reflect Get/Set
定义如下:
Reflect.get(target, name, receiver);
Reflect.set(target, name, value, receiver);
看上去也很好理解,和C#很类似:
target:操作的对象
name:名字字符串
value:要赋的值
receiver:这个比较怪,因为类里可以有getter/setter属性,这两种操作可以在代码块里使用this,如果要用Reflect操作的话,receiver就会代替这个this。
Reflect的操作即使是类的private变量也能获取到。
class Test{
constructor(age: number){
this.age = age;
}
private _age: number;
get age(): number{
return this._age; // this 会被receiver代替
}
set age(value: number) {
this._age = value; // this 会被receiver代替
}
}
class Receiver{
_age: number = 2;
}
let t = new Test(1);
let r = new Receiver();
console.info(Reflect.get(t, "_age")); // 1, 获取t的_age值
console.info(Reflect.get(t, "age")); // 1, 获取t的age值
console.info(Reflect.set(t, "age", 3)); // true, 成功设置age值为3
console.info(Reflect.get(t, "age")); // 3, 再次获取t的age值
console.info(Reflect.get(t, "age", r)); // 2, 表面上是t的age,但实际上获取的是r的age
console.info(Reflect.set(t, "age", 3, r)); // true, 表面上是设置t的age, 实际上是设置r的age值为3
console.info(Reflect.get(r, "_age")); // 3, 直接获取r的_age
apply
上面是属性,还有方法,定义如下:
Reflect.apply(func, thisArg, args);
熟悉JS的朋友应该知道Function也有apply方法,fn.apply(obj, args),可以说是同样的效果。
如果要通过函数名来调用函数,可以这样做:
class Test{
add(a: number, b: number): number{
return a + b;
}
}
let t = new Test();
console.info(Reflect.apply(t["add"], t, [1, 2])); // 3, 虽然t["add"]可以直接执行,不过有时可能需要设置thisArg
define/delete property
define相比之前就真是简单把Object替换成了Reflect,delete和delete obj[name]效果一样。
Reflect.defineProperty(target, propertyKey, attributes);
Reflect.deleteProperty(obj, name);
例子延用上面的对象t:
//define
Reflect.defineProperty(t, 'time', {
value: Date.now()
});
console.info(t.time); // 一串数字
//delete
let d = {time: 111};
console.info(d.time); // 111
Reflect.deleteProperty(d, 'time'); // 成功的话返回true,否则返回false
console.info(d.time); // undefined
可以看到define的参数attributes是一个PropertyDescriptor对象,value就是值,其他还有writable, enumerable, configurable用来控制属性的权限。
对于delete,需要注意的是deleteProperty对class的属性是无效的。
has ownKeys
ownKeys返回的是对象所有属性,包括不可枚举的,如Symbol之类。
has用来判断对象是否有某个属性或方法,包括原型链上的。
class Test{
constructor(name: string){
this.name = name;
}
name: string;
flag: Symbol = Symbol('flag');
getName(): string{
return this.name;
}
}
let obj = new Test('123');
console.info(Reflect.has(obj, 'name')); // true
console.info(Reflect.has(obj, 'flag')); // true
console.info(Reflect.has(obj, 'get')); // true
console.info(Reflect.has(obj, 'toString')); // true
for(let p of Reflect.ownKeys(obj)){
console.info(p); // name, flag
}
其他
Reflect.construct(target,args)
实例化对象除了new之外,还可以用这个,有时候很有用,比如ORM框架里join的字段就可以在设置表时把关联的类型传给字段,使用时用该类型就可以创建出实例。
Reflect.getPrototypeOf(target) 和 Reflect.setPrototypeOf(target, prototype)
分别用于获取和设置对象的原型
Reflect.getOwnPropertyDescriptor(target, name)
设置对象属性的描述对象,如
configurable, writable, enumerable。Reflect.isExtensible(target)
分别用于判断对象是否可扩展。
Reflect.preventExtensions(target)
让一个对象变为不可扩展
Reflect基本上就是把之前Object的方法和一些命令如delete in之类聚到一起,相信ES6之后用Reflect来做这些操作将成为主流。
从C#到TypeScript - Reflect的更多相关文章
- C# vs TypeScript - 高级类型
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - 变量
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - 接口
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - 类
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - function
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - 装饰器
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - Promise
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - Generator
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- 从C#到TypeScript - async await
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
随机推荐
- ubuntu下常用的apt-get 命令参数
apt-cache search package 搜索包 apt-cache show package 获取包的相关信息,如说明.大小.版本等 sudo apt-get install package ...
- Pearson相关系数
理解皮尔逊相关的两个角度 其一, 按照高中数学水平来理解, 皮尔逊相关(Pearson Correlation Coefficient)很简单, 可以看做将两组数据首先做Z分数处理之后, 然后两组数据 ...
- js架构设计模式——前端MVVM框架设计及实现(一)
前端MVVM框架设计及实现(一) 最近抽出点时间想弄个dom模块化的模板引擎,不过现在这种都是MVVM自带的,索性就想自己造轮子写一个简单的MVVM框架了 借鉴的自然还是从正美的avalon开始了,我 ...
- 部署Sharding分片
这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding 的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB 集群. MongoDB 的数据分块称为 ch ...
- I/O流
转自:http://www.cnblogs.com/dolphin0520/p/3791327.html 一.什么是IO Java中I/O操作主要是指使用Java进行输入,输出操作. Java所有的 ...
- doubango(6)--Doubango协议栈中对RTP的管理
相关数据结构 1. tsip_dialog_invite_t 描述: 一个invite_dialog代表了一个invite期间的所有的信令流程,因此,它首先是一个普遍的dialog的特殊化结构, ...
- 安装python2.7.13-64bit & Pycharm在两个python版本之间切换
本来已经安装了32位的python27,但在使用轮廓系数评估k-means模型的优良性时,出现了内存溢出的报错.原来32为的python编译器最多只能使用4GB的内存,所以就打算换成64位的pytho ...
- DotNet加密方式解析--数字签名
马上就要过年回村里了,村里没有wifi,没有4G,没有流量,更加重要的是过几天电脑就得卖掉换车票了,得赶紧写几篇博客. 数据安全的相关技术在现在愈来愈变得重要,因为人们对于自身的信息都有一种保护的欲望 ...
- 定时任务管理中心(dubbo+spring)-我们到底能走多远系列47
我们到底能走多远系列47 扯淡: 又是一年新年时,不知道上一年你付出了多少,收获了多少呢?也许你正想着老板会发多少奖金,也许你正想着明年去哪家公司投靠. 这个时间点好好整理一下,思考总结一下,的确是个 ...
- HNOI2002(伸展树)
营业额统计 Time Limit:5000MS Memory Limit:165888KB 64bit IO Format:%lld & %llu Submit Status ...