Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vue] 4. 为什么要替换 Object.defineProperty? #395

Open
qiilee opened this issue Oct 8, 2019 · 1 comment
Open

[vue] 4. 为什么要替换 Object.defineProperty? #395

qiilee opened this issue Oct 8, 2019 · 1 comment
Labels

Comments

@qiilee
Copy link
Member

qiilee commented Oct 8, 2019

答案:

在 Vue 中,Object.defineProperty 无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。

Object.defineProperty 只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。

@qiilee qiilee added the VUE label Oct 8, 2019
@ChengJunqiang
Copy link

ChengJunqiang commented Jan 14, 2021

其实通过下标给数组设置,是可以触发set方法的,但是像push、shift、unshift等操作数组并不会触发get方法,以下是测试代码

`
function myDefineProperty(data, key, value) {
Object.defineProperty(data, key, {
configurable: true,
get: () => {
console.log("get", "key:", key);
console.log("get", "value:", value);
return value;
},
set: (newValue) => {
console.log("set", "key:", key);
console.log("set", "value:", value);
console.log("set", "newValue:", newValue);
value = newValue;
}

        })
    }

    function observe(data) {
        Object.keys(data).forEach((key) => {
            myDefineProperty(data, key, data[key])
        })
    }

    let arr = ['哈哈', '哦哦', '噢噢'];
    observe(arr);

    //通过下标获取数组会触发get方法
    // console.log(arr[0]);

    //通过下标更改数组的值触发set方法
    // arr[0] = '呵呵';

    //通过push增加数组元素,并不能触发get和set方法
    // arr.push("嘻嘻");

    //通过unshift添加数组元素,会导致索引重置,
    //也就是说将所以元素取出来,然后将unshift参数添加到数组中,然后将原来的数组添加到数组,
    //这时候会导致每次添加会触发set方法、get方法(会执行4次)
    // arr.unshift("可可");
    // console.info(arr[arr.length - 1]);//不会触发get方法,这是因为原数组索引为0,1,2的执行了observe,unshift相当于新增了索引,这时候需要手动observe

    //通过pop删除数组元素,会触发get方法
    // arr.pop();

    //删除数组首个元素,会导致数组索引发生变化,会触发set和get方法,最后一个元素需要手动observe(同unshift)
    // arr.shift();

    //从索引为1的位置开始,删除0个元素,并插入"测试"元素,
    //会导致索引发生变化,最后一个元素需要手动observe(同unshift)
    // arr.splice(1, 0, "测试");

`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants