博客
关于我
JavaScript高级程序设计第四版学习记录-第九章代理与反射
阅读量:569 次
发布时间: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/

你可能感兴趣的文章
看明白这两种情况,才敢说自己懂跨链! | 喵懂区块链24期
查看>>
张一鸣:创业7年,我经历的5件事
查看>>
SQL基础语法
查看>>
git拉取远程指定分支代码
查看>>
CentOS5 Linux编译PHP 报 mysql configure failed 错误解决办法
查看>>
《web安全入门》(四)前端开发基础Javascript
查看>>
pycharm新建文件夹时新建python package和新建directory有什么区别?
查看>>
python中列表 元组 字典 集合的区别
查看>>
python struct 官方文档
查看>>
Android DEX加固方案与原理
查看>>
Android Retrofit2.0 上传单张图片和多张图片
查看>>
iOS_Runtime3_动态添加方法
查看>>
Leetcode第557题---翻转字符串中的单词
查看>>
Problem G. The Stones Game【取石子博弈 & 思维】
查看>>
Unable to execute dex: Multiple dex files
查看>>
Java多线程
查看>>
Unity监听日记
查看>>
AndroidStudio跳到错误位置
查看>>
木马开发的基本理论基础(五)
查看>>
openssl服务器证书操作
查看>>