defineProperty()
defineProperty方法拦截了Object.defineProperty操作 。
文章插图
上面代码中 , defineProperty方法返回false , 导致添加新属性总是无效 。
注意 , 如果目标对象不可扩展(non-extensible) , 则defineProperty不能增加目标对象上不存在的属性 , 否则会报错 。另外 , 如果目标对象的某个属性不可写(writable)或不可配置(configurable) , 则defineProperty方法不得改变这两个设置 。
getOwnPropertyDescriptor()
getOwnPropertyDescriptor方法拦截Object.getOwnPropertyDescriptor() , 返回一个属性描述对象或者undefined 。
文章插图
上面代码中 , handler.getOwnPropertyDescriptor方法对于第一个字符为下划线的属性名会返回undefined 。
getPrototypeOf()
getPrototypeOf方法主要用来拦截获取对象原型 。具体来说 , 拦截下面这些操作 。
- Object.prototype.__proto__
- Object.prototype.isPrototypeOf()
- Object.getPrototypeOf()
- Reflect.getPrototypeOf()
- instanceof
文章插图
上面代码中 , getPrototypeOf方法拦截Object.getPrototypeOf() , 返回proto对象 。
注意 , getPrototypeOf方法的返回值必须是对象或者null , 否则报错 。另外 , 如果目标对象不可扩展(non-extensible) , getPrototypeOf方法必须返回目标对象的原型对象 。
isExtensible()
isExtensible方法拦截Object.isExtensible操作 。
文章插图
ownKeys()
ownKeys方法用来拦截对象自身属性的读取操作 。具体来说 , 拦截以下操作 。
- Object.getOwnPropertyNames()
- Object.getOwnPropertySymbols()
- Object.keys()
- for...in循环
文章插图
上面代码拦截了对于target对象的Object.keys()操作 , 只返回a、b、c三个属性之中的a属性 。
下面的例子是拦截第一个字符为下划线的属性名 。
文章插图
注意 , 使用Object.keys方法时 , 有三类属性会被ownKeys方法自动过滤 , 不会返回 。
- 目标对象上不存在的属性
- 属性名为 Symbol 值
- 不可遍历(enumerable)的属性
文章插图
上面代码中 , ownKeys方法之中 , 显式返回不存在的属性(d)、Symbol 值(Symbol.for('secret'))、不可遍历的属性(key) , 结果都被自动过滤掉 。
ownKeys方法还可以拦截Object.getOwnPropertyNames() 。
文章插图
for...in循环也受到ownKeys方法的拦截 。
文章插图
上面代码中 , ownkeys指定只返回a和b属性 , 由于obj没有这两个属性 , 因此for...in循环不会有任何输出 。
ownKeys方法返回的数组成员 , 只能是字符串或 Symbol 值 。如果有其他类型的值 , 或者返回的根本不是数组 , 就会报错 。
文章插图
实例:Web 服务的客户端
Proxy 对象可以拦截目标对象的任意属性 , 这使得它很合适用来写 Web 服务的客户端 。
文章插图
同理 , Proxy 也可以用来实现数据库的 ORM 层
推荐阅读
- CPU 的一些基本知识总结
- JavaScript sort使用方法
- javascript必会知识及面试重点
- Nginx、HAProxy、LVS三者的优缺点
- Web前端开发基础:HTML、CSS、JavaScript分别实现什么功能?
- 10个 javascript精简代码集合
- JavaScript自定义事件
- JavaScript 常见10种函数
- OOP JavaScript面向对象编程
- JavaScript图表库ECharts使用