问答

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

作者:admin 2021-06-08 我要评论

想写一个双向绑定的 demo,在做的时候出现了一个奇怪的现象 在 defineReactive 里面的 set 改变了形参 value 的值却会改变 vm 实例对象的值 value 是从 obj 里面...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

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

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • PHP-fpm怎么实现进程间同步与互斥的?

    PHP-fpm怎么实现进程间同步与互斥的?

  • ts类型问题

    ts类型问题

  • js不带引号的对象格式字符串怎么转为对

    js不带引号的对象格式字符串怎么转为对

  • Number.prototype.toFixed() 四舍五入

    Number.prototype.toFixed() 四舍五入

腾讯云代理商
海外云服务器