14.数据劫持

35 阅读2分钟

数据劫持

 => 就是在原有的数据的基础上 对这个数据进行一份复刻
 => 就是你有什么我也有什么 就像深浅拷贝
 => 注意: 复刻出来的数据不允许被修改
 => 语法: Object.defineProperty(要劫持的对象,哪个属性 ,{配置项})
 => 配置项
     -> value: 表示的是这个属性的值
     -> writeable: 表示的是这个属性是否可以被重写
         + 默认是 false 表示的是不能被重写(修改)就是只读
         + 选填是 true 表示的是可以重写
     -> enumerable: 表示的是这个属性是否可以被枚举(遍历)
         + 默认是false 表示的是不可以被枚举
         + 选填是 true 表示的是可以被枚举
     -> get: 
         + 就是我们用来获取这个属性的值
         + 是一个函数 就是我们的getter获取器
         + 返回值就是这个属性的值
         + 注意: 这个属性不能和 value 和 writable 一起使用
     -> set: 
         + 也是一个函数
         + 就是用来修改值的
         + 也就是 setter 设置器

数据劫持的代码

let obj = {name:'rose',age:20}
let reulst = {}
Object.defineProperty(reulst,'age',{
    get(){
        return obj.age
    },
    set(val){
        obj.age = val
        box.innerHTML = `我叫 ${ result.name }, 今年 ${ result.age } 岁了`
    }
})
result.age = 100;
这个时候res里面的age也变成了100

数据劫持的封装

        function observer(options,fn) {
        // options: 表示的是你要劫持的原数据
        // fn: 表示的是我们要做的事情
        console.log(fn);

        // 定义一个我们要劫持的对象
        let result = {}

        // 开始劫持
        // 需要知道我们有多少数据需要劫持
        // 遍历我们的原始数据
        for (let k in options) {
            // console.log(k, options[k]);
            Object.defineProperty(result, k, {
                get () {
                    return options[k]
                },
                set (val) {
                    options[k] = val
                    // 这里我们修改完毕以后需要执行一下我们的操作
                    fn(result)
                 }
            }) 
        }

        // 这里需要执行一下我们的操作
        fn(result)

        // 劫持完毕以后需要返回一个劫持后的结果
        return result
    }
    
    
    // let obj = {name:'中国', age: '万岁'}
    // 将来使用的时候
    let res = observer({name:'中国', age: '万岁'}, function (obj) {
        box.innerHTML = `我叫 ${ obj.name }, 今年 ${ obj.age } 岁了`
    })
    res.name = '华夏'
    res.age = 100000