天天看點

ECMAScript中有兩種屬性:資料屬性和通路器屬性。

ECMA-262定義這些特性是為了實作JavaScript引擎用的,是以在JavaScript中不能直接通路它們。為了表示特性是内部值,該規範把它們放在了兩對兒方括号中,例如 [[Enumerable]] 。

ECMAScript中有兩種屬性:資料屬性和通路器屬性。

1. 資料屬性

資料屬性包含一個資料值的位置。在這個位置可以讀取和寫入值。資料屬性有4個描述其行為的特性。

  • [[Configurable]] :表示能否通過 delete 删除屬性進而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為通路器屬性。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性預設值為 true 。
  • [[Enumerable]] :表示能否通過 for-in 循環傳回屬性。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性預設值為 true。
  • [[Writable]] :表示能否修改屬性的值。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性預設值為 true 。
  • [[Value]] :包含這個屬性的資料值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值儲存在這個位置。這個特性的預設值為 undefined 。

對于像前面例子中那樣直接在對象上定義的屬性,它們的[[Configurable]] 、 [[Enumerable]] 和 [[Writable]] 特性都被設定為 true ,而 [[Value]] 特性被設定為指定的值。

例如:

var person = {
    name: “Nicholas”
};           

這裡建立了一個名為 name 的屬性,為它指定的值是 “Nicholas” 。也就是說, [[Value]] 特性将被設定為 “Nicholas” ,而對這個值的任何修改都将反映在這個位置。

要修改屬性預設的特性,必須使用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”
});