美文网首页
Object.defineProperty

Object.defineProperty

作者: Rui___ | 来源:发表于2019-11-05 15:19 被阅读0次

    1.Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性 (getter setter)

    let obj = {
        _a:'', 
        get a(){
            // todo ...
            return this._a
        },
        set a(value){
            this._a = value
        }
    }
    obj.a = 100;// 需要借用一个第三方变量来中转
    console.log(obj.a);
    

    2.Object.defineProperty(obj, prop, descriptor)

    1. obj:必需。目标对象

    2 .prop:必需。需定义或修改的属性的名字

    1. descriptor:必需。目标属性所拥有的特性
    let obj2 ={a:1};
    let val = '';
    Object.defineProperty(obj2,'a',{
      configurable:true,//是否可删除
      //writable:false,//是否可重写
      enumerable:true,//是否可 for in 原型上的方法
        get(){
            return val
        },
        set(value){
            val = value;
        }
    })
    obj2.a=999
    console.log(obj2.a)
    
    

    3.vue中数据劫持 给每个对象都添加一个 getter和setter 当值变化可以 可以实现更新视图的功能

    // vue源码
    function observer(obj) {
      // 缺陷就是无法监控数组的变化
      if (typeof obj !== "object" || obj == null) {
        return;
      }
      for (let key in obj) {
        // 因为defineProperty 需要一个公共的值去修改
        defineReactive(obj, key, obj[key]);
        
      }
    }
    
    let updateView = () => {
      // 更新方法
      console.log("更新");
    };
    // obj  => {a:1,b:2}  key=> a / b  value = 1/2
    function defineReactive(obj, key, value) {
      // Object.defineProperty
      observer(value); // 递归增加getter和setter
      Object.defineProperty(obj, key, {
        get() {
          return value;
        },
        set(val) {
          updateView();
          value = val;
        }
      });
    }
    observer(obj);
    obj.a = 100;
    console.log(obj.a); 
    

    4.以上方式性能不高,并且不能监控数组。所有vue中会将引入 proxy

    相关文章

      网友评论

          本文标题:Object.defineProperty

          本文链接:https://www.haomeiwen.com/subject/qinzvctx.html