Advertisement

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处理器对象中定义的属性统称为捕获器,在阻止代理对象执行特定的操作方面拥有关键作用

常用的捕获器包括

复制代码
    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中对对象进行操作的方法

  • 使用 getPrototypeOf(target) 方法获取目标对象的 prototype 对象。

    • 使用 defineProperty() 函数赋值给目标对象属性。
      为什么要有这个对象
  • 在早期的规范中没有考虑到如何对对象本身进行更加规范的设计。
    于是将API放置在Object上。
    这导致其变得过于复杂,并且由于其作为所有类的父类而被继承到子类中。
    结果发现仅仅依靠现有的API难以满足需求。
    因此,在考虑改进时决定引入Reflect这一工具来集中管理这些操作。

设置、获取、检查是否存在、删除属性获取原型链、设置 prototypes 对结果进行严格按照标准执行的管理。

  • 操作失败一般返回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

全部评论 (0)

还没有任何评论哟~