想写一个双向绑定的 demo,在做的时候出现了一个奇怪的现象
在 defineReactive 里面的 set 改变了形参 value 的值却会改变 vm 实例对象的值
value 是从 obj 里面的属性获得的 const value = obj[key]
,
而在 set 里面改变的只是形参,为何会改变实例对象的
求解!!!
事件触发的地方
node.addEventListener('input', (e) => {
this.$vm.$data[value] = e.target.value
})
class Observer {
constructor(data, vm) {
this.iterationReactive(data)
}
iterationReactive(obj) {
Object.keys(obj).forEach(key => {
const value = obj[key]
if (typeof value === 'object')
this.iterationReactive(value)
else {
this.defineReactive(obj, key, value)
}
})
}
defineReactive(obj, key, value) {
Object.defineProperty(obj, key, {
get() {
return value
},
set(newValue) {
if (newValue === value) return
// 这里
value = newValue
}
})
}
}
###这里实际上是个闭包,我换一种写法也许你就明白了
defineReactive(obj, key, value) {
// 新开一个地址缓存旧值(源码中直接用形参地址存旧值)
let oldValue = value
Object.defineProperty(obj, key, {
get() {
return oldValue
},
set(newValue) {
if (newValue === oldValue) return
// 这里
oldValue = newValue
}
})
}
再附加一段示例代码
function demo(value) {
const updateValue = (newValue) => { value = newValue }
const getValue = () => value
return { getValue, updateValue }
}
const data = 0
const result = demo(data)
console.log(result.getValue())
result.updateValue(1)
console.log(result.getValue())
console.log(data)