使用Object.defineProperty、Object.defineProperties定义JavaScript对象属性

 2016年06月01日    202     声明


Object.definePropertyObject.defineProperties用于定义或修改对象的属性,是ECMAScript 5中定义的两个方法。通过两个方法我可以定义对象的数据属性或访问器属性,前者用于定义或修改对象的一个属性,后者用于定义或修改多个属性。

  1. 对象属性
  2. Object.defineProperty()定义/修改属性
  3. Object.defineProperties()定义/修改多个属性

1. 对象属性

1.1 对象的定义

定义对象时我们可以使用以下几种形式:

使用new Object()创建对象实例:

var site = new Object();
site.name = 'IT笔录';
site.domain = 'itbilu.com';

site.getName = function() {
  return this.name;
}

或者使用字面量创建:

var site = {};
site.name = 'IT笔录';
site.domain = 'itbilu.com';

site.getName = function() {
  return this.name;
}

或者:

var site = {
  name: 'IT笔录'
};

在上面几个示例中,我们使用三种方式定义了具有相同属性和方法的对象。属性可以理解为对象的特征,而方法可以表示对象的行为,而方法可以认为是一种值是函数的特殊属性。


1.2 属性的类型

ECMAScript 5中定义属性使用Object.defineProperty(),定义对象属性时除了可以定义属性值外,还可以定义属性的形为(即:属性的特性-'attribute'),如:使用[[configurable]]定义属性是否可删除、使用[[enumerable]]定义属性是否可枚举。ECMAScript中有两种属性:数据属性和访问器属性。

数据属性

数据属性用于描述数据值及其形为,数据属性有4个描述形为的特性:

  • [[configurable]] - 该特性用于描述属性是否可通过delete删除属性。默认值为true
  • [[enumerable]] - 该特性用于描述属性是否可枚举,即是否可通过for-inObject.keys()枚举。默认值为true
  • [[writable]] - 该特性用于描述属性是否可写(可修改)。默认值为true
  • [[value]] - 该特性用于描述属性的值,属性值的读/写都是操作的这个特性,该特性是一个JavaScript值(值、对象、函数)。默认值为undefined

数据属性描述了属性的值及其形为。我们使用如下方式定义一个属性时:

var site = {
  name: 'IT笔录'
};

这相当于使用Object.defineProperty()方法定义属性并进行了以下设置:

var site = {};

Object.defineProperty(site, "name", {
  enumerable: true,
  configurable: true,
  writable: true,
  value: "IT笔录"
});

访问器属性

访问器,即:gettersetter,这两个属性用于设置或读取属性值([[value]]特性)。访问器可以不定义,不定义时会返回或设置[[value]]特性;设置后将通过这两个方法设置或返回属性值。

  • [[get]] - 对象属性访问器方法(getter),设置后会通过该方法返回属性值。默认值为undefined
  • [[set]] - 对象属性设置器方法(setter),设置后会通过该方法设置值属性。默认值为undefined

我们可以像下面这样定义访问器和设置器:

var site = {
  _name: 'IT笔录'
};

Object.defineProperty(site, "name", {
  get: function() {
    return this._name;
  },
  set: function(value) {
    this._name = value;
  }
});


2. Object.defineProperty()定义/修改属性

Object.defineProperty()用于定义或修改对象的一个属性,其语法结构如下:

Object.defineProperty(obj, prop, descriptor)
  • obj - {Object},要定义属性的对象
  • prop - {String},要定义或修改的属性名
  • descriptor - {Object},要定义或修改的属性的描述,即:数据属性访问器属性

Object.defineProperty()添加一个属性定义,可对已定义的属性进行修改。如,使用Object.defineProperty()通过__proto__特性来设置属性不可继承:

Object.defineProperty(obj, "key", {
  __proto__: null, // 属性不可继承
  value: "static"  // 设置属性默值,但不使用enumerable、configurable、writable特性
});

也可以显式的指定各属性的特性值:

Object.defineProperty(obj, "key", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: "static"
});

还可以通过Object.defineProperty()定义属性的访问/设置器,参考:定义访问器和设置器


3. Object.defineProperties()定义/修改多个属性

Object.defineProperty()可定义可修改对象的一个属性,当定义或修改对象的多个属性时,使用这个方法会比较麻烦。这时可以使用Object.defineProperties()方法来统一设置或修改多个对象属性。该方法语法结构如下:

Object.defineProperties(obj, props)
  • obj - {Object},要定义或修改属性的对象
  • prop - {String},要定义或修改的属性名及属性的特性

如,可以使用Object.defineProperties()方法来定义多个对象属性:

var site = {};

Object.defineProperties(site, {
  name: {
    value: "IT笔录",
    writable: true
  },
  domain: {
    value: "itbilu.com",
    writable: true
  }
});

console.log(site.domain);  // itbilu.com