博客
关于我
JavaScript高级程序设计第四版学习记录-第九章代理与反射
阅读量:581 次
发布时间:2019-03-11

本文共 2192 字,大约阅读时间需要 7 分钟。

代理基础

代理在ECMAScript 6中是一个强大的元编程工具,允许开发者在代码中定义和管理对象的基础操作。通过将目标对象和处理程序结合,代理能够在对目标对象的各种操作前或后拦截并进行处理。目标对象是被代理的对象,处理程序则定义了如何处理对目标对象的访问。

创建空代理

最简单的代理是空代理,通过将一个空对象作为处理程序传给Proxy构造函数,可以创建一个透明的代理:

const target = { id: 'target' };const handler = {};const proxy = new Proxy(target, handler);

在这种情况下,所有对代理的操作都会直接传递到目标对象。例如:

console.log(proxy.id); // 输出 'target'target.id = 'foo';console.log(proxy.id); // 输出 'foo'proxy.id = 'bar';console.log(target.id); // 输出 'bar'

捕获器的作用

捕获器是处理程序中的方法,用于拦截对目标对象的操作。每个捕获器对应一种基本操作,例如getsethas等。通过定义捕获器,可以自定义如何处理目标对象的操作。

例如:

const target = { foo: 'bar' };const handler = {  get(target, property, receiver) {    console.log(`正在访问属性 '${property}'`);    return Reflect.get(...arguments);  }};const proxy = new Proxy(target, handler);console.log(proxy.foo); // 输出 '正在访问属性 'foo''

注意到,这里的target参数实际上是目标对象本身,而receiver则是调用proc时的接受者。

反射API

反射API提供了一套标准的方法,可以轻松地重建被捕获的操作。这些方法对应ECMAScript中的基本操作,名字和功能与原始方法一致。常用的反射方法包括Reflect.getReflect.setReflect.hasReflect.defineProperty等。

例如:

const target = { foo: 'bar' };const handler = {  get(target, property, receiver) {    console.log(`在访问属性 '${property}'`);    return Reflect.get(...arguments);  }};const proxy = new Proxy(target, handler);console.log(proxy.foo); // 输出 'bar'

捕获器不变式

捕获器不变式是确保拦截行为的一套规则,防止不符合预期的行为。例如,如果目标对象的属性是不可配置且不可写的,那么在捕获器修改或设置该属性时会抛出TypeError。

可撤销代理

Proxy.revocable()方法可以创建可撤销的代理。撤销可以通过revoke()函数执行,之后的任何操作都会抛出TypeError。这个功能非常有用,尤其是在处理第三方库时,可以避免意外修改目标对象。

例如:

const target = { id: 'target' };const handler = {};const { proxy, revoke } = Proxy.revocable(target, handler);console.log(proxy.id); // 输出 'target'revoke();console.log(proxy.id); // 输出 TypeError

实用反射API

反射API提供了一些有用方法来替代传统的对象操作。例如,Reflect.defineProperty()返回布尔值,而不是抛出错误,这在处理扩展性问题时非常方便。

const target = {};if (Reflect.defineProperty(target, 'foo', { value: 'bar' })) {  console.log('成功定义属性');} else {  console.log('失败');}

代理的问题与不足

虽然代理在ECMAScript 6中是一个强大的工具,但它仍有一些限制。例如,代理中的this值可能带来问题,特别是在依赖对象标识的代码中。此外,Some内置类型如Date在使用代理时可能会抛出TypeError。

模块总结

在学习ECMAScript 6代理过程中,掌握了以下关键点:

  • 代理的基本使用方法。
  • 捕获器的定义与执行。
  • 反射API的重要性。
  • 捕获器不变式的理解。
  • Proxy.revocable()的可撤销机制。
  • 反射API在实际开发中的应用场景。

通过实际编写代码和处理各种示例,我对代理的理解更加深入,也认识到其在实际项目中的广泛应用。尽管在复杂的场景中可能遇到一些挑战性,但掌握了代理的基础知识后,接下来可以逐步探索其更高级的功能和应用技巧。

转载地址:http://wwztz.baihongyu.com/

你可能感兴趣的文章
mysql 判断表字段是否存在,然后修改
查看>>
mysql 协议的退出命令包及解析
查看>>
mysql 取表中分组之后最新一条数据 分组最新数据 分组取最新数据 分组数据 获取每个分类的最新数据
查看>>
mysql 多个表关联查询查询时间长的问题
查看>>
mySQL 多个表求多个count
查看>>
mysql 多字段删除重复数据,保留最小id数据
查看>>
MySQL 多表联合查询:UNION 和 JOIN 分析
查看>>
MySQL 大数据量快速插入方法和语句优化
查看>>
mysql 如何给SQL添加索引
查看>>
mysql 字段区分大小写
查看>>
mysql 字段合并问题(group_concat)
查看>>
mysql 字段类型类型
查看>>
MySQL 字符串截取函数,字段截取,字符串截取
查看>>
MySQL 存储引擎
查看>>
mysql 存储过程 注入_mysql 视图 事务 存储过程 SQL注入
查看>>
MySQL 存储过程参数:in、out、inout
查看>>
mysql 存储过程每隔一段时间执行一次
查看>>
mysql 存在update不存在insert
查看>>
Mysql 学习总结(86)—— Mysql 的 JSON 数据类型正确使用姿势
查看>>
Mysql 学习总结(87)—— Mysql 执行计划(Explain)再总结
查看>>