[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` 。