自学内容网 自学内容网

js高阶-监听对象的操作

控制与监听对象的行为

需求:监听对象中的属性设置与访问的过程

Object.defineProperty()

缺点
设计初衷是设置属性描述符,监听更加丰富的操作比如新增属性,删除操作是无能为力的

// 1.监听对象的某个属性的操作

Object.defineProperty(obj,'name',{

    set:function(val){

        console.log("设置值",val);

        this._name=val //使用一个属性来存值

    },

    get:function(){

        console.log("获取值");

        return this._name

    }

})

//2.监听某个对象的所有属性操作

Object.keys(obj).forEach((key)=>{

    let val = obj[key] // 暂存原值

    Object.defineProperty(obj,key,{

        get(){

            console.log(`get key ${key}`);

            return val

        },

        set(newVal){

            console.log(`set key ${key}:`,newVal);

            val=newVal

        }

    }

    )

})

Proxy

es6新增类,用来创建代理对象,通过给对象创建代理对象,之后所有对对象进行的操作都可以通过代理对象进行
new Proxy(target,handler)

handler

handler处理器对象,中的属性称为捕获器,拦截对代理对象的一些操作,一共13个
实现原理
内部维护一个对象,关联了target与handler,当对代理对象进行操作的时候,会先送到handler
常用的捕获器
| 方法 | 对应操作 | 描述 |
| ---- | -------- | ------------------ |
| get | 属性读取 | 拦截属性读取操作 |
| set | 属性设置 | 拦截属性设置操作 |
| has | in操作 | 拦截属性存在性检查 |
| deleteProperty |delete操作 | 拦截删除属性操作 |

let proxyObj=new Proxy(obj,{

    //获取值 target是目标对象 key是属性

    get(target , key){

        console.log(`检测到get`);

        return target[key]

    },

    //设置值

    set(target,key,newVal){

        console.log("检测到set");

        target[key] = newVal

    },

    //监听in 的操作符

    has(target,key){

        console.log("监听in操作");

        return key in target

    },

    //监听delete

    deleteProperty(target , key){

        console.log("监听到delete操作");

        delete target[key]

    },

})

Reflect

ES6新增的内置对象,所有方法都是静态方法,像Math
提供很多操作js对象的方法,类似Object中操作对象的方法

  • Reflect.getPrototypeOf(target) ~~ Object.getPrototypeOf()
  • Reflect.defineProperty()~~ Object.defineProperty()
    为什么要有这个对象
  • 早期的规范中,没有考虑到对对象本身操作如何设计更加规范,于是将API放到了Object上面,导致Object类越来越臃肿,而它做为所有类的父类,会被继承到子类中,东西过多加重子类负担
  • Object做为构造函数,将这些操作放在它上面不太合理
    所以新增Reflect 来集中管理这些操作

set,get,has,deleteProperty,
getPrototypeOf,setPrototypeOf
对结果处理非常规范

  • 操作失败一般返回false
  • 操作成功返回值/true
let obj={

    name:'zhangsan',

    age:18

}

  

console.log("检查name属性是否存在",Reflect.has(obj,'name')); //检查name属性是否存在 true

  

console.log("获取name属性",Reflect.get(obj,'name'));//获取name属性 zhangsan

  

Reflect.set(obj,'name','lisi');

console.log(obj.name);//lisi

  

Reflect.deleteProperty(obj,'age');

console.log(obj.age);//undefined

console.log("检查age属性是否存在",Reflect.has(obj,'age')); //false

原文地址:https://blog.csdn.net/qq_73270720/article/details/145248128

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!