ECMA-262 第 5 版在定義只有內部才用的特性(attribute)時,描述了屬性(property)的各類特徵。定義這些屬性是爲了實現JavaScript引擎用的,所以在JavaScript中不能直接訪問它們。爲了我表示特性是內部值,改規範把它們放在了兩對兒方括號中,例如[[Enumerable]]。瀏覽器
ECMAScript 中有兩種屬性:數據屬性和訪問器屬性函數
數據屬性包含一個數據值的位置。在這個位置能夠讀取和寫入值。數據屬性有 4 個描述其行爲的特性。this
做用:修改屬性默認的特性
參數:屬性所在的對象、屬性的名字、和一個描述符對象。描述符對象的屬性必須是configurable、enumerable、writable 和 value。code
Object.defineProperty(person, "name", { writable: false, value: "Nicholas" }); alert(person.name); //"Nicholas" person.name = "Greg"; alert(person.name); //"Nicholas"
一旦把configurable屬性定義爲不可配置的,就不能再把它變回可配置了。此時,再調用 Object.defineProperty()方法修改除 writable 以外
的特性,都會致使錯誤htm
var person = {}; Object.defineProperty(person, "name", { configurable: false, value: "Nicholas" }); //拋出錯誤 Object.defineProperty(person, "name", { configurable: true, value: "Nicholas" });
在調用 Object.defineProperty()方法時,若是不指定,configurable、enumerable 和writable 特性的默認值都是 false(未調用改方法時默認值都爲true)對象
訪問器屬性不含數據值;他們包含一對兒getter和setter函數(不是必需的)。在讀取訪問器屬性時,會調用getter函數,這個函數負責返回有效的值;在寫入訪問器屬性時,會調用setter函數並傳入新值。這個函數負責如何處理數據ip
訪問器的四個屬性:get
訪問器屬性不能直接定義,必須使用 Object.defineProperty()來定義。it
var book = { _year: 2004, //下劃線是一種經常使用的記號,用於表示只能經過對象方法訪問的屬性 edition: 1 }; Object.defineProperty(book, "year", { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2005; alert(book.edition); //2
支持 ECMAScript 5 的這個方法的瀏覽器有 IE9+(IE8 只是部分實現)、Firefox 4+、Safari 5+、Opera 12+ 和 Chrome 。在這個方法以前,要建立訪問器屬性,通常都使用兩個非標準的方法:__defineGetter__()和__defineSetter__()。這兩個方法最初是由 Firefox 引入的,後來 Safari 三、Chrome 1 和 Opera 9.5 也給出了相同的實現io
var book = { _year: 2004, edition: 1 }; //定義訪問器的舊有方法 book.__defineGetter__("year", function(){ return this._year; }); book.__defineSetter__("year", function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } }); book.year = 2005; alert(book.edition); //2 AccessorPropertiesExample02.htm 在不支持 Object.defineProperty() 方法的瀏覽器中不能修改 [[Configurable]] 和 [[Enumerable]]。
Object.defineProperties()方法,利用這個方法能夠經過描述符一次定義多個屬性。這個方法接收兩個對象參數:第一個對象是要添加和修改器屬性的對象,第二個對象的屬性和第一個對象中要添加或修改的屬性一一對象。
var book = {}; Object.defineProperties(book, { _year: { value: 2004 }, edition: { value: 1 }, year: { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } } });
Object.getOwnPropertyDescriptor()方法,能夠取得給定屬性的描述符。這個方法接收兩個參數: 屬性所在的對象和要讀取器描述符的屬性名稱。返回值是一個對象,若是是訪問器屬性,這個對象的屬性有configurable、enumerable、get 和 set;若是是數據屬性,這個對象的屬性有 configurable、enumerable、writable 和 value。
var book = {}; Object.defineProperties(book, { _year: { value: 2004 }, edition: { value: 1 }, year: { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } } }); var descriptor = Object.getOwnPropertyDescriptor(book, "_year"); alert(descriptor.value); //2004 alert(descriptor.configurable); //false