JavaScript数据属性和访问器属性

数据属性

数据属性有4个特性(描述属性的各种特征):

  1. [[Configurable]]:表示能否通过 delete 删除属性。
  2. [[Enumerable]]:表示 for…in 循环是否会遍历该属性。
  3. [[Writable]]:表示能否修改属性的值。
  4. [[Value]]:属性的数据值。

在对象上直接定义的属性和通过对象字面量定义的属性的前3个特性的默认值为true[[Value]]特性被设置为指定的值。
要修改属性默认的特性,必须使用Object.defineProperty()方法。在使用此方法创建一个新属性时,前3个特性的默认值为false[[Value]]默认值为undefined

var person = {};
Object.defineProperty(person, "name", {
	configurable: false,
	value: "Tom"
});

访问器属性

访问器属性也有4个特性:

  1. [[Configurable]]:表示能否通过 delete 删除属性。
  2. [[Enumerable]]:表示 for…in 循环是否会遍历该属性。
  3. [[Get]]:在读取属性时调用的函数。默认值为undefined
  4. [[Set]]:在写入属性时调用的函数。默认值为undefined
    var book = {
    	_year: 2020,
    	edition: 1
    };
    Object.defineProperty(book, "year", {
    	get: function() {
    		return this._year;
    	},
    	set: function(newValue) {
    		if(newValue > 2020) {
    			this._year = newValue;
    			this.edition += newValue - 2020;
    		}
    	}
    });
    book.year = 2021;
    alert(book.edtion);	//2
    当设置一个属性的值会导致其他属性发生变化时,可以使用访问器属性。

定义多个属性

使用Object.defineProperties()方法可以同时定义多个属性。

var person = {};
Object.defineProperties(person, {
	firstName: {
		writable: true,
		value: "Tom"
	},
	lastName: {
		writable: true,
		value: "miao"
	},
	age: {
		enumerable: true,
		value: 12
	},
	fullName: {
		get: function() {
			return this.firstName + " " + this.lastName;
		},
		set: function(newVal) {
			var name = newVal.split(" ");
			this.firstName = name[0] || "";
			this.lastName = name[1] || "";
		}
	}
});

读取属性的特性

使用Object.getOwnPropertyDescriptor()方法可以得到属性的描述符。

var desc1 = Object.getOwnPropertyDescriptor(person, "firstName");
alert(desc1.writable);		//true
alert(desc1.enumerable);	//false
alert(desc1.value);		//"Tom"
var desc2 = Object.getOwnPropertyDescriptor(person, "fullName");
alert(desc2.value);		//undefined
alert(typeof desc2.get);	//"function"