为了更好地操作对象新增了 Proxy 和 ReflectES6
Proxy
相当于在目标对象之前加一层“拦截”,可以对外界的访问进行过滤和改写
可以改变一些默认的语言行为,用自己的定义覆盖了语言的原始定义,属于一种“元编程”(meta programming),即对编程语言进行编程
创建
const p = new Proxy(target, handler)
target:被 Proxy 包装的对象(任何类型的对象,包括原生数组、函数,甚至是另一个代理) handler:代理配置,是一个对象,可以拦截对于对象的大多数操作
支持的拦截操作
handler | 作用 |
---|---|
get | 拦截对象属性的读取 |
set | 拦截对象属性的设置 |
has | 拦截 propKey in proxy 的操作 |
deleteProperty | 拦截 delete proxy[propKey] 的操作 |
ownKeys | 拦截 Object.getOwnPropertyNames(proxy) 、Object.getOwnPropertySymbols(proxy) 、Object.keys/values/entries 、for...in 循环 |
getOwnPropertyDescriptor | 拦截 Object.getOwnPropertyDescriptor(proxy, propKey) 、Object.keys/values/entries 、for...in 循环 |
defineProperty | 拦截 Object.defineProperty(proxy, propKey, propDesc) 、Object.defineProperties(proxy, propDescs) |
getPrototypeOf | 拦截 Object.getPrototypeOf(proxy) |
setPrototypeOf | 拦截 Object.setPrototypeOf(proxy, proto) |
isExtensible | 拦截 Object.isExtensible(proxy) |
preventExtensions | 拦截 Object.preventExtensions(proxy) |
apply | 拦截 Proxy 实例作为函数调用的操作,如 proxy(...) 、proxy.call(...) 、proxy.apply(...) |
construct | 拦截 Proxy 实例作为构造函数调用的操作,如 new proxy(...args) |
代理应该在所有地方都完全替代目标对象。目标对象被代理后,任何地方都不应该再引用原来的目标对象,否则很容易混乱
Reflect
是一个内建对象,不是函数(不能使用 new 调用)
作用
- 将 Object 属于语言内部的一些方法放到 Reflect 上
- 修改某些 Object 方法的返回结果,使其更合理
- 让 Object 操作都变成函数行为,Reflect.has(obj, name) 代替 name in obj
- Proxy 上有的 Reflect 上都有,所以在 Proxy 上修改默认行为时,都可以通过 Reflect 获取到默认行为,
- 配合 Proxy 使用,执行原生行为
Reflect 支持调用原始的、语言内部的数据操作方法,以得到原始的结果,执行原始的行为