兼收并蓄 TypeScript - 进阶: proxy, reflect

news/2024/9/20 12:29:20

源码 https://github.com/webabcd/TypeScriptDemo
作者 webabcd

兼收并蓄 TypeScript - 进阶: proxy, reflect

示例如下:

advanced\proxy_reflect.ts

{// Proxy - 代理(拦截目标对象的属性操作和函数操作)let target = {name: 'webabcd',age: 40,get hello() {return this.name + this.age;}}let handler = {get: function(target:any, propertyKey:string, receiver:any) { // receiver 就是 Proxy 实例本身console.log("get: "+ propertyKey);return target[propertyKey];},set: function(target:any, propertyKey:string, value:any, receiver:any) { // receiver 就是 Proxy 实例本身console.log("set: " + propertyKey);target[propertyKey] = value;return true; // 对于 handler 的 set() 来说,必须要有 return true},has: function(target:any, propertyKey:string){console.log("has: " + propertyKey);return propertyKey in target;}/** 其他可代理的方法如下:* construct() - 执行 new Proxy() 时* getPrototypeOf() - 执行 Object.getPrototypeOf(proxy) 时* setPrototypeOf() - 执行 Object.setPrototypeOf(proxy) 时* preventExtensions() - 执行 Object.preventExtensions(proxy) 时* isExtensible() - 执行 Object.isExtensible(proxy) 时* defineProperty() - 执行 Object.defineProperty(proxy) 时* ownKeys() - 执行 Object.getOwnPropertyNames(proxy) 时* deleteProperty() - 执行 delete proxy.prop 时*/}// Proxy - 让 handler 处理 target 的属性和方法let proxy = new Proxy(target, handler);proxy.name = "wanglei"; // 会走到 handler 的 set()let name = proxy.name; // 会走到 handler 的 get()let exists = ("name" in proxy); // 会走到 handler 的 has()// 通过 handler 的 apply() 代理函数的调用function target2(a:number, b:number) {return a + b;}let handler2 = {apply: function(target:any, ctx:any, args:any[]) {console.log("apply: " + args.join(","));return target(...args);}};let proxy2 = new Proxy(target2, handler2);console.log(proxy2(100, 50)); // 150// 通过 handler 的 construct() 代理构造函数class Target3 {  constructor(public a: number, public b: number) {  }  hello(): number {  return this.a + this.b;  }  }  let handler3 = {construct(target:any, argArray:any[]) {console.log("construct: "+argArray.join(","));return new target(...argArray);}};let proxy3 = new Proxy(Target3, handler3);console.log(new proxy3(100, 50).hello()); // 150// Reflect - 反射let target4 = {name: 'webabcd',age: 40,get hello() {return this.name + this.age;}}// Reflect.get() - 获取指定对象的指定属性console.log(Reflect.get(target4, "hello")); // wanglei40// Reflect.get() - 获取指定对象的指定属性(对象中的 this 会指向 Reflect.get() 的第 3 个参数)console.log(Reflect.get(target4, "hello", {name: "xyz"})); // xyzundefined// Reflect.set() - 设置指定对象的指定属性Reflect.set(target4, 'name', "abc");console.log(Reflect.get(target4, "name")); // abcclass Target5 {  constructor(public a: number, public b: number) {  }  hello(p:string): string {  return `${p} ${this.a + this.b}`;}  }  // Reflect.apply() - 调用指定的函数//     第 1 个参数:目标函数//     第 2 个参数:目标函数的 this 指向的对象//     第 3 个参数:传入目标函数的参数列表let t5 = new Target5(1, 2);console.log(Reflect.apply(t5.hello, {a:100, b:200}, ['xxx'])); // xxx 300class Target6 {  constructor(public a: number, public b: number) {  }  hello(): number {  return this.a + this.b;  }  }  // Reflect.construct() - 调用构造函数并传参let t6 = Reflect.construct(Target6, [100, 200]);console.log(t6.hello()); // 300/** 关于 Reflect 除了上面说的,还有如下:* 注:这些都可以在 Object 中找到相同的用法,可以参见 class/prototype.js 中的关于 Object 的相关说明以及 basic/object.js 中的关于 Object 的相关的说明* defineProperty() - 类似 Object.defineProperty()* deleteProperty() - 类似 delete obj.prop* getPrototypeOf() - 类似 Object.getPrototypeOf()* setPrototypeOf() - 类似 Object.setPrototypeOf()* preventExtensions() - 类似 Object.preventExtensions()* isExtensible() - 类似 Object.isExtensible()* ownKeys() - 类似 Object.getOwnPropertyNames()** 注:能用 Reflect 的方法就用 Reflect 的,而不要再用 Object 的了*/// 通过 Proxy 和 Reflect 实现察者模式let myObj = {name: 'webabcd'}let myHandler = {set: function(target:any, propertyKey:string, value:string, receiver:any) {const result = Reflect.set(target, propertyKey, value, receiver);observerList.forEach(observer => observer(propertyKey, value));return result;}}const observerList: Function[] = [];const observer = (fn:Function) => observerList.push(fn);const observable = (obj:any) => new Proxy(obj, myHandler);// 指定观察者observer((propertyKey:string, value:string) => {console.log(`我是观察者 1,发现 myObj 的 ${propertyKey} 的值变为了 ${value}`);});observer((propertyKey:string, value:string) => {console.log(`我是观察者 2,发现 myObj 的 ${propertyKey} 的值变为了 ${value}`);});// 指定可被观察的对象,属性发生变化时通知所有观察者let observableObj = observable(myObj);observableObj.name = "wanglei";
}

源码 https://github.com/webabcd/TypeScriptDemo
作者 webabcd

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/62491.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

帝国cms备份500错误 帝国cms刷新失败

当使用帝国CMS进行备份或刷新操作时,遇到500错误或刷新失败的情况,通常是因为服务器端出现了问题。以下是一些常见的原因和解决方法: 常见原因服务器端错误服务器返回了500 Internal Server Error。 服务器端脚本执行失败。权限问题文件或目录权限设置不当,导致Web服务器无…

IEEE 1838-2019协议翻译——第五章 Serial test access ports

目录 5.1 Primary test access port5.1.1 Specifications5.1.2 Description 5.2 Primary test access port controller5.2.1 Specifications5.2.2 Description5.3 Secondary test access port (STAP)5.3.1 Specifications5.3.2 Description 5.4 Secondary test access port con…

帝国cms登陆错误次数 帝国cms登陆错误次数超过

帝国CMS为了防止暴力破解攻击,默认设置了登录错误次数的限制。当登录错误次数超过设定值时,系统会暂时禁止登录一段时间。如果你遇到了登录错误次数超过限制的问题,可以采取以下几种方法来解决:等待重试默认情况下,帝国CMS会在你连续输入错误密码5次后锁定账户60分钟。这时…

win10远程控制教程,使用工具:ToDesk

win10远程控制教程,使用工具:ToDesk 最近用到远程控制软件的地方可太多了 不但能随时解决突发工作问题,还能和很多电子设备互连👍 用了一堆软件下来,发现还是ToDesk远程控制最趁手 今天小圈先来出个【win10电脑远程控制教程】💻 答应我,打工人都要来学会好吗!🔵实现…

SimpleAISearch:C# + DuckDuckGo 实现简单的AI搜索

SimpleAISearch:C# + DuckDuckGo 实现简单的AI搜索最近AI搜索很火爆,有Perplexity、秘塔AI、MindSearch、Perplexica、memfree、khoj等等。 在使用大语言模型的过程中,或许你也遇到了这种局限,就是无法获取网上最新的信息,导致回答的内容不是基于最新的信息,为了解决这个…

关于codepage

codepage就是各国的文字编码和Unicode之间的映射表。系统使用映射表就可以在各种编码中做转换。 查表 以gbk为例,它的codepage=936, 可以从ftp://ftp.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT下载映射表。 “中”字的映射为验证 https://www.toolhelper…

七牛云——存储区域说明

​​ 区域和访问域名存储区域 Region 区域 Region ID 域名华东-浙江 z0 空间管理:http(s)://uc.qiniuapi.com​源站上传:http(s)://up-z0.qiniup.com​源站下载:http(s)://iovip-z0.qiniuio.com​对象管理:http(s)://rs-z0.qiniuapi.com​对象列举:http(s)://rsf-z0.qiniu…

linux 下安装 RabbitMq 及 .net core 实操多种模式

当前系统Debian GNU/Linux 12 安装命令1、sudo apt update    //更新系统2、sudo apt-get install rabbitmq-server    //安装rabbitMq 服务3、sudo service rabbitmq-server start     //启动 rabbitMq4、sudo systemctl enable rabbitmq-server //设置开机…