美文网首页
Object.defineProperty() 基础使用

Object.defineProperty() 基础使用

作者: kevin5979 | 来源:发表于2020-12-06 10:29 被阅读0次

需求: 对一个对象实现监视,即监视对象所有属性的增删改查

概念

Object.defineProperty():方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

方法

Object.defineProperty(obj,prop,descriptor);

简单的使用
  • 新增属性
let obj = {};
Object.defineProperty(obj,"name",{
  value: "kevin",
  writable: true,    // 赋予写权限
  enumerable: true,  // 可遍历权限
  configurable: true // 可配置的权限
})
console.log(obj);  // { name: 'kevin' }

// 1.1 通过defineProperty定义赋值的属性不能改变,
// 必须添加 **writable: true** 才能修改对象的属性
obj.name = "Tom";
console.log(obj);  // { name: 'Tom' }

// 1.2 通过defineProperty定义赋值的属性不能遍历
// 必须添加 **enumerable: true** 才能修遍历
for (const key in obj) {
  console.log(key,obj[key]);   // name Tom
}
// 1.3 通过defineProperty定义赋值的属性不能删除
// 必须添加 **configurable: true** 才能删除
delete obj.name;
console.log(obj);  // {}

get/set使用
  • 通过属性的get/set来监听属性变化,获取属性自动调用get方法,设置属性自动调用set方法
  • get/set 和Object.defineProperty中 value、writable 属性不能共存
let obj2 = {}
let oldValue = "kevin"
// get/set 和 value、writable 不能共存
Object.defineProperty(obj2, "name", {
  // value: "kevin",
  // writable: true,
  enumerable: true,
  configurable: true,
  set(newValue) {
    console.log("执行set方法,旧值为", newValue);
    if (oldValue !== newValue) {
      console.log("执行set方法,新值为", newValue);
      oldValue = newValue;
    }
  },
  get() {
    console.log("执行get方法,属性为", oldValue);
    return oldValue;
  }
})

obj2.name = "Tom";  // 执行set方法,旧值为 kevin.   执行set方法,新值为 Tom
console.log(obj2.name); // 执行get方法,属性为 Tom

实现对象属性的检测
// 监视对象类
class ObserverObject {
  // 构造器
  constructor(obj) {
    this.observer(obj)
  }

  // 监视方法
  observer(obj) {
    if (obj && typeof obj === "object") {
      for (const key in obj) {
        this.observerRealize(obj, key, obj[key]);
      }
    }
  }

  // 监视实现
  observerRealize(obj, key, value) {
    // 如果属性的取值是一个对象, 也需要给这个对象的所有属性添加get/set方法
    // 例子: value为对象
    this.observer(value)
    Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get: () => {
        return value;
      },
      set: (newValue) => {
        console.log('数据的变化前', value);
        if (newValue !== value) {
          // 如果属性的取值是一个对象, 也需要给这个对象的所有属性添加get/set方法
          // 例子: newValue为对象
          this.observer(newValue);
          value = newValue;
          console.log('数据的变化后', newValue);
        }
      }
    })
  }
}

let obj = {
  name: "kevin",
  detail: {
    age: 18
  }
}

new ObserverObject(obj);

obj.name = "Tom";  // 数据的变化前 kevin , 数据的变化后 Tom
obj.detail.age = 20;  // 数据的变化前 18 , 数据的变化后 20

obj.name = { a: "aaa" };  // 数据的变化前 Tom , 数据的变化后 { a: [Getter/Setter] }
obj.name.a = "bbb";  // 数据的变化前 aaa ,  数据的变化后 bbb

需求完成

END

相关文章

网友评论

      本文标题:Object.defineProperty() 基础使用

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