Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
407 views
in Technique[技术] by (71.8m points)

Vue 双向绑定的 setter ,改变形参影响实例对象

想写一个双向绑定的 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
            }
        })
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

这里实际上是个闭包,我换一种写法也许你就明白了

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)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...