拦截器Object.defineProperty(对象,“属性名“,{对属性做一些规定}) 与Proxy(target,{})

拦截器Object.defineProperty(对象,“属性名”,{对属性做一些规定})

  • 作用:获取或新增一个属性,在该属性发生操作时,拦截操作,执行拦截器里规定的操作
Object.defineProperty(对象,"属性名",{
	writable:true,//该属性是否可以修改,true可改变,默认false
	configurable:true,//该属性的描述符是否可以改变,比如true时,该属性可删除,默认false不可删除
	enumerable:true,//该属性是否可枚举,true可枚举,默认false
	value://修改该属性的值,这里可以写任何值,包括数值,对象,函数,正则表达式等
	set(val){return val+1}//当该属性被修改时,执行set后面的代码
	get(){return }//当该属性被获取时,执行get后面的代码,属性的值改为return后面的值
})
  • 注意
    configurable定义为false时,后面就不能再改回true,并且之后再对该属性的拦截器定义除了value和writable其他都会报错
    不写get时,只要有set的拦截,就会自动生成一个get拦截get(){return undefined}
    set(val){}小括号里面的val值就是获取该属性的操作后获取到的值
    writable为false时,value就会无效
    当有set或get时,写writable和value就会报错

拦截器代理

proxy(target,handler)

  • target目标对象
  • handler也是一个对象,指定target的行为,就是写拦截器里面的代码
//写法一
let target = {
    name: "gg",
    age: 10
}
let handler = {
    get: function(obj, k) {//obj实参对应的对象属性的集合数组,也就是target的数组形式,k拦截到的对象的键(属性)
        console.log('getting '+k);
        return obj[k]; // 不能用obj.k
    },
    set: function(obj, k, value) {//obj实参对应的对象属性的集合数组,k对象的键(属性),value改变属性值时的值
        console.log('setting '+key);
        obj[k] = value;
    }
}
let p = new Proxy(实参对象名, 拦截器名)
p.name     // 执行 handler.get
p.age = 25 // 执行 handler.set

//写法二,handler直接写在Proxy()里面
let p = new Proxy(实参对象名, {
    get: function(obj, k) {
        console.log('getting '+k);
        return obj[k]; 
    },
    set: function(obj, k, value) {
        console.log('setting '+key);
        obj[k] = value;
    }
})
  • 注意点:
    代理拦截里只写set也会自动生成一个get,但是这个get的返回值是拦截的属性值本身
    代理拦截里不写set会自动生成一个set,里面有一句obj[k] = value,就是把修改的值赋值给对象的该属性
    设置一个就可以对对象里的所有属性进行拦截。
    proxy相当于一个构造函数,要用let 变量名 = new Proxy(target,handler),通过这个变量.属性名才会触发拦截,对象.属性名不会拦截

使用代理,实现数据的双向绑定

let i = document.querySelector("#sid");
let obj = {
    sid:1
}
let proxy = new Proxy(obj,{
    set(o,k,val){
        o[k] = val;
        i.value = val;
    }
})       
i.addEventListener("input",function(){
    proxy.sid = this.value;
    //这里也可以obj.sid=this.value(这个不会被拦截),但是最好用proxy,既然要拦截他每次改值都拦截,因为拦截之后除了赋值还能在get里面另外多做一些操作
})

同时绑定多个输入框

id:<input type="text" id="sid">
name:<input type="text" id="sname">
tel:<input type="text" id="tel">
<script>
    let i = document.querySelectorAll("#sid");
    let sn = document.querySelectorAll("#sname");
    let tel = document.querySelectorAll("#tel");
    let ipt = document.querySelectorAll("input");
    let obj = {
        sid:1,
        sname:"张三",
        tel:000
    }
    let proxy = new Proxy(obj,{
        set(o,k,val){
            //改变对象的值
            o[k] = val;
            //改变页面的值
            switch(k){
                case "sid":i.value = val;break;
                case "sname":sn.value = val;break;
                case "tel":tel.value = val;break;
            }
        }
    })      
    ipt.forEach(function(value,index){
        ipt[index].addEventListener("input",function(){
            switch(ipt[index].id){
                case "sid":proxy.sid = this.value;break;
                case "sname":proxy.sname = this.value;break;
                case "tel":proxy.tel = this.value;break;
            }
        })
    }) 
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值