Ethan Zhu
©️朱俊辉
All Rights Reserved.

理解Object.defineProperty的作用

Object.defineProperty,顾名思义就是对对象定义属性,据我所知定义对象属性有三种方式

// 1. 点语法定义
obj.name = 'hello world'
// 2. 方括号定义
obj['name'] = 'hello world'
//3. defineproperty方法定义
Object.defineproperty(obj, 'name', {
    value: 'hello world'
})

上面的方法看得出来,obj.name的方式定义一个属性是最方便的,而defineproperty看上去却很繁琐,下面我来分析下这个Object.defineProperty方法

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

官方定义的很标准我就不追加定义了

  • 语法

Object.defineProperty(object, propertyname, descriptor)

  • 参数
  1. object 必需。 要在其上添加或修改属性的对象。 这可能是一个本机 JavaScript对象(即用户定义的对象或内置对象)或 DOM 对象。
  2. propertyname 必需。 一个包含属性名称的字符串。
  3. descriptor 必需。 属性描述符。 它可以针对数据属性或访问器属性。
  • 属性的状态设置

主要关注的是这个descriptor参数,该参数可设置的值有

  1. 【value】 属性的值,默认为 undefined。
  2. 【writable】 该属性是否可写,如果设置成 false,则任何对该属性改写的操作都无效(但不会报错),对于像前面例子中直接在对象上定义的属性,这个属性该特性默认值为为 true。
    var someOne = { };
    Object.defineProperty(someOne, "name", {
        value:"coverguo" , //由于设定了writable属性为false 导致这个量不可以修改
        writable: false 
    });  
    console.log(someOne.name); // 输出 coverguo
    someOne.name = "linkzhu";
    console.log(someOne.name); // 输出coverguo

     

  3. 【configurable]】如果为false,则任何尝试删除目标属性或修改属性以下特性(writable, configurable, enumerable)的行为将被无效化,对于像前面例子中直接在对象上定义的属性,这个属性该特性默认值为为 true。
    var someOne = { };
    Object.defineProperty(someOne, "name", {
        value:"coverguo" ,
        configurable: false 
    });  
    delete someOne.name; 
    console.log(someOne.name);// 输出 coverguo
    someOne.name = "linkzhu";
    console.log(someOne.name); // 输出coverguo

     

  4. 【enumerable】 是否能在for-in循环中遍历出来或在Object.keys中列举出来。对于像前面例子中直接在对象上定义的属性,这个属性该特性默认值为为 true。
    注意 在调用Object.defineProperty()方法时,如果不指定, configurable, enumerable, writable特性的默认值都是false,这跟之前所 说的对于像前面例子中直接在对象上定义的属性,这个特性默认值为为 true。并不冲突,如下代码所示:

    //调用Object.defineProperty()方法时,如果不指定
    var someOne = { };
    someOne.name = 'coverguo';
    console.log(Object.getOwnPropertyDescriptor(someOne, 'name'));
    //输出 Object {value: "coverguo", writable: true, enumerable: true, configurable: true}
    
    //直接在对象上定义的属性,这个特性默认值为为 true
    var otherOne = {};
    Object.defineProperty(otherOne, "name", {
        value:"coverguo" 
    });  
    console.log(Object.getOwnPropertyDescriptor(otherOne, 'name'));
    //输出 Object {value: "coverguo", writable: false, enumerable: false, configurable: false}

     

  5. 【get】一旦目标对象访问该属性,就会调用这个方法,并返回结果。默认为 undefined。
  6. 【set】 一旦目标对象设置该属性,就会调用这个方法。默认为 undefined。

 

 

从上面,可以得知,我们可以通过使用Object.defineProperty,来定义和控制一些特殊的属性,如属性是否可读,属性是否可枚举,甚至修改属性的修改器(setter)和获取器(getter)

2018-08-30
暂无评论

发表评论