Proxy 和 defineProperty 的比较
Proxy 和 defineProperty 的比较
可拦截属性的比较
属性 | defineProperty | Proxy | 描述 |
---|---|---|---|
get | 支持 | 支持 | (target, propKey, receiver) 拦截对象属性的读取,比如 proxy.foo 和proxy[‘foo’]。 |
set | 支持 | 支持 | (target, propKey, value, receiver) 拦截对象属性的设置,比如proxy.foo = v 或 proxy[‘foo’] = v,返回一个布尔值。 |
has | 不支持 | 支持 | (target, propKey) 拦截 propKey in proxy 的操作,返回一个布尔值。 |
deleteProperty | 不支持 | 支持 | (target, propKey) 拦截 delete proxy[propKey] 的操作,返回一个布尔值。 |
ownKeys | 不支持 | 支持 | (target) 拦截Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for…in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而 Object.keys() 的返回结果仅包括目标对象自身的可遍历属性。 |
getOwnPropertyDescriptor | 不支持 | 支持 | (target, propKey) 拦截Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。 |
defineProperty | 不支持 | 支持 | (target, propKey, propDesc) 拦截Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。 |
preventExtensions | 不支持 | 支持 | (target) 拦截 Object.preventExtensions(proxy),返回一个布尔值。 |
getPrototypeOf | 不支持 | 支持 | (target) 拦截 Object.getPrototypeOf(proxy),返回一个对象。 |
isExtensible | 不支持 | 支持 | (target) 拦截 Object.isExtensible(proxy),返回一个布尔值。 |
setPrototypeOf | 不支持 | 支持 | (target, proto) 拦截 Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。 |
apply | 不支持 | 支持 | (target, object, args) 拦截 Proxy 实例作为函数调用的操作,比如proxy(…args)、proxy.call(object, …args)、proxy.apply(…)。 |
construct | 不支持 | 支持 | (target, args) 拦截 Proxy 实例作为构造函数调用的操作,比如new proxy(…args)。 |
## 兼容性的比较 ### proxy的兼容性如下
desktop | mobile | server | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Proxy | ChromeFull support49 | EdgeFull support12 | FirefoxFull support18 | Internet ExplorerNo supportNo | OperaFull support36 | SafariFull support10 | WebView AndroidFull support49 | Chrome AndroidFull support49 | Firefox for AndroidFull support18 | Opera AndroidFull support36 | Safari on iOSFull support10 | Samsung InternetFull support5.0 | Node.jsFull support6.0.0 |
Proxy() constructor | ChromeFull support49 | EdgeFull support12 | FirefoxFull support18 | Internet ExplorerNo supportNo | OperaFull support36 | SafariFull support10 | WebView AndroidFull support49 | Chrome AndroidFull support49 | Firefox for AndroidFull support18 | Opera AndroidFull support36 | Safari on iOSFull support10 | Samsung InternetFull support5.0 | Node.jsFull support6.0.0 |
revocable | ChromeFull support63 | EdgeFull support12 | FirefoxFull support34 | Internet ExplorerNo supportNo | OperaFull support50 | SafariFull support10 | WebView AndroidFull support63 | Chrome AndroidFull support63 | Firefox for AndroidFull support34 | Opera AndroidFull support46 | Safari on iOSFull support10 | Samsung InternetFull support8.0 | Node.jsFull support6.0.0 |
### defineProperty兼容性如下
desktop | mobile | server | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
defineProperty | ChromeFull support5 | EdgeFull support12 | FirefoxFull support4 | Internet ExplorerFull support9 | OperaFull support11.6 | SafariFull support5.1 | WebView AndroidFull support1 | Chrome AndroidFull support18 | Firefox for AndroidFull support4 | Opera AndroidFull support12 | Safari on iOSFull support6 | Samsung InternetFull support1.0 | Node.jsFull support0.10.0 |
使用总结
- Object.defineProperty 并非不能监控数组下标的变化(vue2中不能通过下标的方式更新数组)
- Object.defineProperty 对属性的劫持需要深度遍历,新增属性需要手动Observe
- Proxy 可以使用业务场景和支持的API更多和全面
- Proxy 作为新标准,后续会有持续的性能优化
- Proxy 兼容性是硬伤,在对兼容性有要求的业务场景下无法使用