JavaScript Proxy基本知识梳理( 四 )


defineProperty()
defineProperty方法拦截了Object.defineProperty操作 。

JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , defineProperty方法返回false , 导致添加新属性总是无效 。
注意 , 如果目标对象不可扩展(non-extensible) , 则defineProperty不能增加目标对象上不存在的属性 , 否则会报错 。另外 , 如果目标对象的某个属性不可写(writable)或不可配置(configurable) , 则defineProperty方法不得改变这两个设置 。
getOwnPropertyDescriptor()
getOwnPropertyDescriptor方法拦截Object.getOwnPropertyDescriptor() , 返回一个属性描述对象或者undefined 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , handler.getOwnPropertyDescriptor方法对于第一个字符为下划线的属性名会返回undefined 。
getPrototypeOf()
getPrototypeOf方法主要用来拦截获取对象原型 。具体来说 , 拦截下面这些操作 。
  • Object.prototype.__proto__
  • Object.prototype.isPrototypeOf()
  • Object.getPrototypeOf()
  • Reflect.getPrototypeOf()
  • instanceof
下面是一个例子 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , getPrototypeOf方法拦截Object.getPrototypeOf() , 返回proto对象 。
注意 , getPrototypeOf方法的返回值必须是对象或者null , 否则报错 。另外 , 如果目标对象不可扩展(non-extensible) ,  getPrototypeOf方法必须返回目标对象的原型对象 。
isExtensible()
isExtensible方法拦截Object.isExtensible操作 。
JavaScript Proxy基本知识梳理

文章插图
 
ownKeys()
ownKeys方法用来拦截对象自身属性的读取操作 。具体来说 , 拦截以下操作 。
  • Object.getOwnPropertyNames()
  • Object.getOwnPropertySymbols()
  • Object.keys()
  • for...in循环
下面是拦截Object.keys()的例子 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码拦截了对于target对象的Object.keys()操作 , 只返回a、b、c三个属性之中的a属性 。
下面的例子是拦截第一个字符为下划线的属性名 。
JavaScript Proxy基本知识梳理

文章插图
 
注意 , 使用Object.keys方法时 , 有三类属性会被ownKeys方法自动过滤 , 不会返回 。
  • 目标对象上不存在的属性
  • 属性名为 Symbol 值
  • 不可遍历(enumerable)的属性

JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , ownKeys方法之中 , 显式返回不存在的属性(d)、Symbol 值(Symbol.for('secret'))、不可遍历的属性(key) , 结果都被自动过滤掉 。
ownKeys方法还可以拦截Object.getOwnPropertyNames() 。
JavaScript Proxy基本知识梳理

文章插图
 
for...in循环也受到ownKeys方法的拦截 。
JavaScript Proxy基本知识梳理

文章插图
 
上面代码中 , ownkeys指定只返回a和b属性 , 由于obj没有这两个属性 , 因此for...in循环不会有任何输出 。
ownKeys方法返回的数组成员 , 只能是字符串或 Symbol 值 。如果有其他类型的值 , 或者返回的根本不是数组 , 就会报错 。
JavaScript Proxy基本知识梳理

文章插图
 
实例:Web 服务的客户端
Proxy 对象可以拦截目标对象的任意属性 , 这使得它很合适用来写 Web 服务的客户端 。
JavaScript Proxy基本知识梳理

文章插图
 
同理 , Proxy 也可以用来实现数据库的 ORM 层




推荐阅读