当前位置: 首页 > news >正文

JavaScript高级程序设计(第四版)--学习记录之代理与反射

代理

代理是目标对象的抽象。

创建空代理

代理是使用Proxy构造函数创建的。Proxy接收两个参数:目标对象和处理程序对象。缺一不可。要创建空代理,可以传一个简单的对象字面量作为处理程序对象,从而让所有操作畅通无阻地抵达目标对象。

const target = { id: 'target' 
}; 
const handler = {}; 
const proxy = new Proxy(target, handler); 
// id 属性会访问同一个值
console.log(target.id); // target 
console.log(proxy.id); // target 
// 给目标属性赋值会反映在两个对象上
// 因为两个对象访问的是同一个值
target.id = 'foo'; 
console.log(target.id); // foo 
console.log(proxy.id); // foo 
// 给代理属性赋值会反映在两个对象上
// 因为这个赋值会转移到目标对象
proxy.id = 'bar'; 
console.log(target.id); // bar 
console.log(proxy.id); // bar 
// hasOwnProperty()方法在两个地方
// 都会应用到目标对象
console.log(target.hasOwnProperty('id')); // true 
console.log(proxy.hasOwnProperty('id')); // true 
// Proxy.prototype 是 undefined 
// 因此不能使用 instanceof 操作符
console.log(target instanceof Proxy); // TypeError: Function has non-object prototype 
'undefined' in instanceof check 
console.log(proxy instanceof Proxy); // TypeError: Function has non-object prototype 
'undefined' in instanceof check 
// 严格相等可以用来区分代理和目标
console.log(target === proxy); // false

定义捕获器

捕获器就是在处理程序对象中定义的“基本操作的拦截器”。每个处理程序对象可以包含零个或多个捕获器,每个捕获器都对应一种基本操作,可以直接或间接在代理对象上调用。每次在代理对象上调用这些基本操作时,代理可以在这些操作传播到目标对象之前先调用捕获器函数,从而拦截并修改相应的行为。

const target = { foo: 'bar' 
}; 
const handler = { // 捕获器在处理程序对象中以方法名为键get() { return 'handler override'; } 
}; 
const proxy = new Proxy(target, handler); 
console.log(target.foo); // bar 
console.log(proxy.foo); // handler override 
console.log(target['foo']); // bar 
console.log(proxy['foo']); // handler override 
console.log(Object.create(target)['foo']); // bar 
console.log(Object.create(proxy)['foo']); // handler override

捕获器不变式

使用捕获器几乎可以改变所有基本方法的行为,但也不是没有限制。根据 ECMAScript 规范,每个捕获的方法都知道目标对象上下文、捕获函数签名,而捕获处理程序的行为必须遵循“捕获器不变式” (trap invariant)。捕获器不变式因方法不同而异,但通常都会防止捕获器定义出现过于反常的行为。

可撤销代理

revocable()方法支持撤销代理对象与目标对象的关联,撤销代理的操作是不可逆的。撤销函数是幂等的,调用多少次的结果都一样。

const target = { foo: 'bar' 
}; 
const handler 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 完美解决ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: NO)
  • Perl语言入门到高级学习
  • 【教程】Github Page 添加自定义域名
  • SQL Server和Oracle数据库的实时同步
  • python通过pyinstaller库进行打包,运行时提示缺少ODBC驱动
  • STM32智能仓库管理系统教程
  • 原创作品—数据可视化大屏
  • pytest系列——pytest_runtest_makereport钩子函数获取测试用例执行结果
  • TIA博途与威纶通触摸屏无实物仿真调试的具体方法示例
  • 用Vue3和Plotly.js绘制交互式3D散点图
  • 新浪API系列:支付API打造无缝支付体验,畅享便利生活(3)
  • python库 - modelscope
  • Java面试八股之MySQL索引B+树、全文索引、哈希索引
  • Springboot项目实训--day2
  • LabVIEW在半导体自动化测试中的应用
  • 【391天】每日项目总结系列128(2018.03.03)
  • 2017 年终总结 —— 在路上
  • CSS实用技巧干货
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • java中具有继承关系的类及其对象初始化顺序
  • jquery ajax学习笔记
  • mysql 5.6 原生Online DDL解析
  • PHP那些事儿
  • ReactNative开发常用的三方模块
  • Redash本地开发环境搭建
  • Spring Boot快速入门(一):Hello Spring Boot
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • 安装python包到指定虚拟环境
  • 半理解系列--Promise的进化史
  • 删除表内多余的重复数据
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • (31)对象的克隆
  • (arch)linux 转换文件编码格式
  • (C)一些题4
  • (附源码)计算机毕业设计SSM疫情居家隔离服务系统
  • (转)【Hibernate总结系列】使用举例
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)ORM
  • (转)Unity3DUnity3D在android下调试
  • .cn根服务器被攻击之后
  • .CSS-hover 的解释
  • .md即markdown文件的基本常用编写语法
  • .net 4.0 A potentially dangerous Request.Form value was detected from the client 的解决方案
  • .net 获取某一天 在当月是 第几周 函数
  • .Net 执行Linux下多行shell命令方法
  • @DateTimeFormat 和 @JsonFormat 注解详解
  • @vueup/vue-quill使用quill-better-table报moduleClass is not a constructor
  • [ A*实现 ] C++,矩阵地图
  • []Telit UC864E 拨号上网