数据劫持和数据代理

数据劫持

定义:数据劫持,指的是在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果。

其实就是一种给对象添加属性的方法
就是复刻一份对象 ,原来的对象是普通对象。原来的对象通过Object.defineProperty 设置一遍,会有一个新的对象,那么这个对象就是被监听的对象
方法一语法:

Object.defineProperty(obj,props,descriptor)
obj:必需。目标对象
prop:必需。需定义或修改的属性的名字
descriptor:必需。目标属性所拥有的特性

    Object.defineProperty(obj,props,{
        配置项
        value:设置的值,
        writable:表示是否允许被修改  默认false,
        enumerable:表示是否允许被枚举(遍历) 默认false,
        get(){},
        set(){}
    })

get:是一个函数,称之为获取器 getter。在访问这个属性的时候才会触发get方法,函数的返回值会作为该属性的值返回

注:不能和value 还有writable 一起使用

set:是一个函数,设置器setter。在改变这个属性的时候触发,而且能监听想改变的值。

例子:p标签中内容随input输入框中内容变化而变化

//数据劫持的实现
    var input = document.querySelector('input')
    var p = document.querySelector('p')
    var btn = document.querySelector('.btn')
    
    let obj = {
        name:'小明',
        age:50,
    }
    function Observe(origin,fn){
        let target = {}
        for(let key in origin){
            Object.defineProperty(target,key,{
                get(){
                    return origin[key]
                },
                set(val){
                     origin[key] = val
                     fn(target) //input事件
                }
            })
        }
        fn(target) //p中获取data.name事件
        return target
    }
    let res = Observe(obj,(data)=>{
         p.innerHTML = data.name
    })
    
    input.oninput = function(){
        res.name = this.value
    }

方法二语法:

Object.defineProperties是自己劫持到自己身上。
缺点:
后期动态通过点语法添加的成员 不能被监听的

Object.defineProperties(对象,{
key:配置,
})

//数据劫持的实现方法二:
    let origin = {
            name: "张三",
            age: 18
    }
    
    for(var key in origin){
        Object.defineProperties(origin,{
            //复刻一份原始对象的属性
            ['_' + key]:{
                value:origin[key],
                writable:true,
            },
            [key]:{
                get(){
                    return origin['_' + key]
                },
                set(val){
                     origin['_' + key] = val
                }
            }
        })
    }
    origin.sex = 'nan'
    console.log(origin); //{sex: 'nan', _name: '张三', _age: 18}

数据代理

Proxy

返回值就是你代理的结果

优点:

后期动态通过点语法添加的成员 也可以被监听的到

//数据代理
     var input = document.querySelector('input')
        var p = document.querySelector('p')
    let obj = {
        name:'小明',
        age:33,
    }
    function Observe(obj,fn){
        let target = new Proxy(obj,{
            get(origin,property){
                //property 表示每一个原始对象中的属性,默认遍历
                return origin[property]
            },
            set(origin,property,val){
                origin[property] = val
                fn(target)
                return true
            }
        })
        fn(target)
        return target
    }
    let res = Observe(obj,(data)=>{
          p.innerHTML = data.name
    })
    res.sex = 'nan'
    console.log(res); //Proxy(Object) {name: '小明', age: 33, sex: 'nan'}
    
    input.oninput = function(){
        res.name = this.value
    }
    console.log(res); //Proxy(Object) {name: '小明', age: 33, sex: 'nan'}
    
     let arr = [{id:1,name:'袜子'},{id:2,name:'手机'}]
         
        let  app = Observe(arr,(res)=>{
            console.log(res)  //Proxy(Array) {0: {…}, 1: {…}}
        })
        console.log(app) //Proxy(Array) {0: {…}, 1: {…}}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值