ES6 Proxy 与 Object.defineProperty 的优劣对比?
程序员文章站
2022-07-16 18:05:19
...
Proxy 的优势如下:
- Proxy 可以直接监听数组的变化
- Proxy 可以直接监听对象而非属性
- Proxy 有 13 种拦截方法,比 Object.defineProperty 要更加丰富的多
Object.defineProperty 的优势如下:
- 兼容性好
Object.defineProperty (obj, prop, descriptor) 的问题主要有三个:
- 无法监听数组的变化
- 必须遍历对象的每个属性
- 必须深层遍历嵌套的对象
(1)无法监听数组的变化
Vue 把会修改原来数组的方法定义为变异方法。
变异方法例如 push、pop、shift、unshift、splice、sort、reverse等,是无法触发 set 的。
非变异方法,例如 filter,concat,slice 等,它们都不会修改原始数组,而会返回一个新的数组。
Vue 的做法是把这些变异方法重写来实现监听数组变化。
const aryMethods = [
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse',
]
const arrayAugmentations = []
aryMethods.forEach((method) => {
// 这里是原生 Array 的原型方法
let original = Array.prototype[method]
// 将 push, pop 等封装好的方法定义在对象 arrayAugmentations 的属性上
// 注意:是实例属性而非原型属性
arrayAugmentations[method] = function () {
console.log('我被改变啦!')
// 调用对应的原生方法并返回结果
return original.apply(this, arguments)
}
})
let list = ['a', 'b', 'c']
// 将我们要监听的数组的原型指针指向上面定义的空数组对象
// 这样就能在调用 push, pop 这些方法时走进我们刚定义的方法,多了一句 console.log
list.__proto__ = arrayAugmentations
list.push('d') // 我被改变啦!
// 这个 list2 是个普通的数组,所以调用 push 不会走到我们的方法里面。
let list2 = ['a', 'b', 'c']
list2.push('d') // 不输出内容
(2)必须遍历对象的每个属性
使用 Object.defineProperty 多数情况下要配合 Object.keys 和遍历,于是就多了一层嵌套。
并且由于遍历的原因,假如对象上的某个属性并不需要“劫持”,但此时依然会对其添加“劫持”。
Object.keys(obj).forEach((key) => {
Object.defineProperty(obj, key, {
// ...
})
})
(3)必须深层遍历嵌套的对象
当一个对象为深层嵌套的时候,必须进行逐层遍历,直到把每个对象的每个属性都调用 Object.defineProperty() 为止。
以上。
上一篇: ES6----let and const
下一篇: 主成分分析(PCA)
推荐阅读
-
ES6学习笔记之map、set与数组、对象的对比
-
网站设计:单页网站与多页网站的优劣势对比分析
-
ES6 Proxy 与 Object.defineProperty 的优劣对比?
-
Proxy 与 Object.defineProperty对比
-
Object.defineProperty与proxy进行对比
-
Proxy 与Object.defineProperty介绍与对比
-
用object.defineproperty()和proxy实现简单的双向绑定,并比较两者优劣
-
vue的双向数据绑定(Object.defineProperty(),和es6的Proxy的底层封装是Object.defineProperty()封装的);...
-
浅谈Object.defineProperty与Proxy的区别
-
Proxy 与Object.defineProperty 实现响应式的区别