ECMA-262定義這些特性是爲了實現JavaScript引擎用的,所以在JavaScript中不能直接訪問它們。爲了表示特性是內部值,該規範把它們放在了兩對兒方括號中,例如 [[Enumerable]] 。瀏覽器
ECMAScript中有兩種屬性:數據屬性和訪問器屬性。code
數據屬性包含一個數據值的位置。在這個位置能夠讀取和寫入值。數據屬性有4個描述其行爲的特性。對象
對於像前面例子中那樣直接在對象上定義的屬性,它們的[[Configurable]] 、 [[Enumerable]] 和 [[Writable]] 特性都被設置爲 true ,而 [[Value]] 特性被設置爲指定的值。ip
例如:it
var person = { name: 「Nicholas」 };
這裏建立了一個名爲 name 的屬性,爲它指定的值是 「Nicholas」 。也就是說, [[Value]] 特性將被設置爲 「Nicholas」 ,而對這個值的任何修改都將反映在這個位置。table
要修改屬性默認的特性,必須使用ECMAScript 5的 Object.defineProperty() 方法。這個方法接收三個參數:屬性所在的對象、屬性的名字和一個描述符對象。其中,描述符(descriptor)對象的屬性必須是: configurable 、 enumerable 、 writable 和value 。設置其中的一或多個值,能夠修改對應的特性值。配置
例如:循環
var person = {}; Object.defineProperty(person, 「name」, { writable: false, value: 「Nicholas」 }); alert(person.name); //「Nicholas」 person.name = 「Greg」; alert(person.name); //「Nicholas」
這個例子建立了一個名爲 name 的屬性,它的值 「Nicholas」 是隻讀的。這個屬性的值是不可修改的,若是嘗試爲它指定新值,則在非嚴格模式下,賦值操做將被忽略;在嚴格模式下,賦值操做將會致使拋出錯誤。相似的規則也適用於不可配置的屬性。方法
例如:數據
var person = {}; Object.defineProperty(person, 「name」, { configurable: false, value: 「Nicholas」 }); alert(person.name); //「Nicholas」 delete person.name; alert(person.name); //「Nicholas」
把 configurable 設置爲 false ,表示不能從對象中刪除屬性。若是對這個屬性調用 delete ,則在非嚴格模式下什麼也不會發生,而在嚴格模式下會致使錯誤。並且,一旦把屬性定義爲不可配置的,就不能再把它變回可配置了。此時,再調用 Object.defineProperty() 方法修改除 writable 以外的特性,都會致使錯誤:
var person = {}; Object.defineProperty(person, 「name」, { configurable: false, value: 「Nicholas」 }); //拋出錯誤 Object.defineProperty(person, 「name」, { configurable: true, value: 「Nicholas」 });
也就是說,能夠屢次調用Object.defineProperty() 方法修改同一個屬性,但在把configurable 特性設置爲 false 以後就會有限制了。
在調用 Object.defineProperty() 方法時,若是不指定, configurable 、 enumerable和 writable 特性的默認值都是 false 。多數狀況下,可能都沒有必要利用 Object.defineProperty() 方法提供的這些高級功能。不過,理解這些概念對理解JavaScript對象卻很是有用。
IE8是第一個實現 Object.defineProperty() 方法的瀏覽器版本。然而,這個版本的實現存在諸多限制:只能在DOM對象上使用這個方法,並且只能建立訪問器屬性。因爲實現不完全,建議讀者不要在IE8中使用 Object.defineProperty() 方法。