vue2 的 Object.defineProperty 为什么不在 get 中递归?为什么 vue3 Proxy 中可以?

vue2 的 Object.defineProperty 为什么不在 get 中递归?为什么 vue3 Proxy 中可以?

这是 vue2 采取数据监听的方式

function defineReactive(target, key, value) {

//深度监听

observer(value)

Object.defineProperty(target, key, {

get() {

return value

}

})

}

这是 vue3 采取数据监听的方式,在 get 中才去监听

// reactive 中有 Proxy 操作

const handler = {

get: function (obj, prop) {

const res = Reflect.get(obj, prop)

if (typeof res === 'object') {

return reactive(res, handler)

}

return res

}

}

const p = reactive(bigData, handler)

vue3 为了避免多次 get 导致的多次递归,在 reactive 中会判断是否已经被代理过,如果是会直接返回对象
vue2 为什么不这么做,反而是直接在代理属性时就选择数据监听,如果选择在 get 中,当数据被访问时再递归子对象/数组,这样不就不会有递归的性能问题了吗?


回答:

可以看下我的这篇文章
反向操作,用 Object.defineProperty 重写 @vue/reactivity

虽然实际上没多大应用场景,但是可以看看怎么用defineProperty实现vue3的


回答:

可能是因为Object.defineProperty是针对对象单个属性进行监听的,所以要放在get中的话,需要一个一个遍历,性能影响是一方面,还有一方面是vue2中数组是不监听的,如果是一个数组对象,数组不监听,走不到get,还怎么监听里面的对象。

而proxy是针对对象本身去监听的,无论数组还是对象都可以监听,运行时监听可以减少其他无用数据监听带来的消耗


回答:

所以,综合楼上所说,vue3判断对象是否被代理过是使用了WeakMap,这是一个ES6的语法,在当时的vue2是不可能使用的,当时来说对于WeakMap又没有什么好的替代品,所以vue2没有采用这样的判断机制。不知道我说的对否

以上是 vue2 的 Object.defineProperty 为什么不在 get 中递归?为什么 vue3 Proxy 中可以? 的全部内容, 来源链接: utcz.com/p/937357.html

回到顶部