详解Object.defineProperty()方法


        Object.defineProperty是一个用于定义或修改对象属性的方法。它提供了一种更底层和灵活的方式来定义属性,可以设置属性的配置(如可枚举性、可配置性、可写性等),并且可以定义属性的getter和setter函数。

语法:

Object.defineProperty(obj, prop, descriptor)

 参数说明:

        - `obj`:要定义属性的对象

        - `prop`:要定义或修改的属性名称。

        - `descriptor`:一个描述符对象,用于定义或修改属性的特性。它有以下可选的键值:

                - `value`:属性的值,默认为`undefined`。

                - `writable`:属性的可写性。默认为`false`,即该属性为只读属性。

                - `enumerable`:属性的可枚举性。默认为`false`,即该属性不可枚举。

                - `configurable`:属性的可配置性。默认为`false`,即该属性不可被删除。         

                - `get`:获取属性值的函数。

                - `set`:设置属性值的函数。

直接看代码:

没有设置writable、enumerable、configurable属性,默认都为false,age属性不可枚举,不可修改,不可删除。

  let person = {
    name: "张三",
    sex: "男",
  };
  Object.defineProperty(person, 'age', {
      value: 18,
  })

  console.log(person); // {name: '张三', sex: '男', age: 18}

  for (p in person) { // 这里由于Object.defineProperty中没有设置enumerable:true,所以age属性不会参与枚举遍历
      console.log(p);
      // name
      // sex
  }

  person.age = 19;     // 这里由于Object.defineProperty中没有设置writable:true,所以修改不会生效
  console.log(person); // {name: '张三', sex: '男', age: 18}

  delete person.age;   // 这里由于Object.defineProperty中没有设置configurable:true,所以删除不会生效
  console.log(person); // {name: '张三', sex: '男', age: 18}

此时修改是person对象上的age值是无效的,值实际上没有更新  

设置了writable、enumerable、configurable属性的值为true之后,age属性可以被枚举,可以被修改,可以被删除。 

  let person = {
    name: "张三",
    sex: "男",
  };
  Object.defineProperty(person, "age", {
    value: 18,
    enumerable: true, //控制属性是否可以枚举,默认值是false
    writable: true, //控制属性是否可以被修改,默认值是false
    configurable: true, //控制属性是否可以被删除,默认值是false
  });

  console.log(person); // {name: '张三', sex: '男', age: 18}

  for (p in person) {
    // 这里由于Object.defineProperty中设置了enumerable:true,所以age属性参与了枚举遍历
    console.log(p);
    // name
    // sex
    // age
  }

  person.age = 19; // 这里由于Object.defineProperty中设置了writable:true,所以修改生效了
  console.log(person); // {name: '张三', sex: '男', age: 19}

  delete person.age; // 这里由于Object.defineProperty中设置了configurable:true,所以删除生效了
  console.log(person); // {name: '张三', sex: '男'}

 Object.defineProperty  还可以设置getter和setter方法

let number = 18;
let person = {
    name: "张三",
    sex: "男",
};
// 此外 Object.defineProperty  还可以设置getter和setter方法
Object.defineProperty(person, "age", {
  // value:18,
  // enumerable:true, //控制属性是否可以枚举,默认值是false
  // writable:true, //控制属性是否可以被修改,默认值是false
  // configurable:true, //控制属性是否可以被删除,默认值是false

  //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
  get() {
    console.log("有人读取age属性了");
    return number;
  },

  //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
  set(value) {
    console.log("有人修改了age属性,且值是", value);
    number = value;
  },
});

console.log('person', person);
console.log('number', number);

注意事项:

         Object.defineProperty() 设置了getter和setter方法之后,就不能再设置value属性,否则控制台报错:Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object>


文章作者: 程序猿小野
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 程序猿小野 !
评论