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