[TOC]
## 理解對象
`new` 方式創建一個 `Object` 實例
```js
var person = new Object();
person.name = "SpiritLing";
person.age = 22;
person.job = "web;
person.sayName = function(){
console.log(this.name);
}
```
字面量創建一個 `Object` 實例
```js
var person = {
name: "SpiritLing",
age: 22,
job: "web",
sayName: function(){
console.log(this.name);
}
}
```
上面兩個具有相同的屬性和方法。這些屬性在創建時都帶有一些特征值(characteristic),JavaScript 是通過這些特征值來定義它們的行為
### 屬性類型
ECMA-262 第5版在定義只有內部才用的特性(attribute)時,描述了屬性(property)的各種特征。ECMA-262定義這些特性是為了實現JavaScript引擎用的,因此在JavaScript中不能直接訪問它們。為了表示特性是內部值,該規范把它們放在兩對方括號中,例如:[[Enumerable]] 。盡管 ECMA-262 第3版 的定義有些不同,但本書只參考第5版的描述。
ECMAScript 中有兩種屬性:數據屬性和訪問器屬性。
#### 數據屬性
- [[`Configurable`]]:表示能否通過 `delete` 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。像前面的例子中那樣直接在對象上定義的屬性,它們的這個特性默認值為 `true`。
- [[`Enumerbale`]]:表示能否通過 `for-in` 循環返回屬性。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性默認值為 `true`。
- [[`Writable`]]:表示能否修改屬性的值。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性默認為 `true`。
- [[`Value`]]:包含這個屬性的數據值。讀取屬性值的時候,從這個位置讀;寫入屬性值的時候,把新值保存在這個位置。這個特性的默認值為 `undefined` 。
對于前面的例子中那樣直接在對象上定義的屬性,它們的 `[[Configurable]]`、`[[Enumerbale]]`、`[[Writable]]` 特性都被設置成 `true` ,而 `[[Value]]` 被設置成特定的值。
要修改屬性默認的特性,必須使用 ECMAScript 5 的 `Object.defineProperty()` 方法。這個方法接受三個參數:屬性所在的對象、屬性的名字,和一個描述符對象。其中,描述符(descriptor)對象的屬性必須是:`Configurable`、`Enumerbale`、`Writable`、`Value`。設置其中一個或多個值,可以修改對應的特性值。
- [[Writable]] 改變例子
```js
var person={};
Object.defineProperty(person,"name",{
writable: false,
value: "SpiritLing"
})
console.log(person.name); //"SpiritLing"
person.name="博客";
console.log(person.name); //"SpiritLing"
```
- [[Configurable]] 改變例子
```js
var person={};
Object.defineProperty(person,"name",{
configurable: false,
value: "SpiritLing"
})
console.log(person.name); //"SpiritLing"
delete person.name;
console.log(person.name); //"SpiritLing"
```
- [[Enumerbale]] 改變例子
```js
var person={};
Object.defineProperty(person,"name",{
enumerbale: false,
value: "SpiritLing"
})
console.log(person.name); //"SpiritLing"
for(var o in person){
console.log(person[o]) //undefined
}
```
> 當然在上面的屬性特性更改后,某些特性會出現報錯,比如 `configurable` 改變成 `false` ,則在普通模式下使用 `delete` 時,不會出現問題,但是在嚴格模式下,則會出現報錯。
#### 訪問器屬性
訪問器屬性不包含數據值;它們包含一對 `getter` 和 `setter` 函數(不過,這兩個函數不是必需的)。在讀取訪問器屬性時,會調用 `getter` 函數,這個函數負責返回有效的值;在寫入訪問器的屬性時,會調用 `setter` 函數并傳入新值,這個函數負責決定如何處理函數。
- `[[Configurable]]`:表示能否通過 `delete` 刪除屬性從而重新定義屬性,能否修改屬性的特性,或者能否把屬性修改為訪問器屬性。像前面的例子中那樣直接在對象上定義的屬性,它們的這個特性默認值為 `true`。
- `[[Enumerbale]]`:表示能否通過 `for-in` 循環返回屬性。像前面例子中那樣直接在對象上定義的屬性,它們的這個特性默認值為 `true`。
- `[[Get]]`:在讀取屬性時調用的函數。默認值為 `undefined` 。
- `[[Set]]`:在寫入屬性時調用的函數。默認值為 `undefined` 。