数据劫持

其原理:在Vue中其实就是通过Object.defineProperty来劫持对象属性的setter和getter操作,并“种下”一个监听器,当数据发生变化的时候发出通知。

那我们先来了解一下Object.defineProperty:

  • 语法
    Object.defineProperty(obj,target,texing)

  • 参数说明:
    obj:-操作的对象
    target:需定义或修改的属性的名字
    texing:目标属性所拥有的特性

  • 可供定义的特性列表
    value:属性的值
    writable:如果为false,属性的值就不能被重写。
    configurable: 如果为false,则任何尝试删除目标属性或修改属性性以下特性(writable, configurable, enumerable)的行为将被无效化。
    enumerable: 是否能在for...in循环中遍历出来或在Object.keys中列举出来。
    set:一旦目标属性被赋值,就会调回此方法。
    get: 一旦目标属性被访问就会调回此方法,并将此方法的运算结果返回用户。

注:当使用了getter或setter方法,不允许使用writable和value这两个属性

举个栗子(数据劫持):
         // 劫持
        function hijack(data) {
            if (!data || typeof data !== 'object') {
                return;
            }
            // 拿到对象里的每个key 和 value
            Object.keys(data).forEach(item => {
                // item:key  data[item]:value
                defineProperty(data, item, data[item]);
            });
        }
        function defineProperty(obj, key, value) {
            // 如果value是个对象则调用 hijack重新遍历(对象嵌套对象)
            hijack(value);
            Object.defineProperty(obj, key, {
                enumerable: true,
                configurable: true,
                get: function () {
                    console.log('只要访问了该属性,我就会执行');
                    return value;
                },
                set: function (newValue) {
                    if (value === newValue) {
                        return
                    }
                    console.log('更新了!', value + '->' + newValue);
                    value = newValue;
                }
            });
        }
        var obj = {
            a: 1,
            b: 2
        }
        hijack(obj);

这个是控制台的结果:


image.png

你可能感兴趣的:(数据劫持)