Object.defineProperty

2019-11-05  本文已影响0人  Rui___

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

上一篇下一篇

猜你喜欢

热点阅读