### 基本類型
string、number、boolean、null、undefined、object,除object外,其他5個均不是對象,即便`typeof null`結果為object。
### 內置對象
String、Number、Boolean、Object、Function、Array、Date、RegExp、Error
`"I am string"`本身不是對象,`"I am string" instanceof String`結果為false。獲取長度、訪問某個字符等字符串操作必須在String對象上操作,之所以我們能直接使用,是因為js內部幫我們將字符串轉換成了String對象,Number同理。
### 內容
obj[xx]中的xx永遠是字符串,即便你傳入的不是也會被轉換成字符串:
```
var obj = {};
obj[true] = "foo";
obj[3] = "bar";
obj[obj] = "baz";
obj["true"]; //foo
obj["3"]; //bar
obj["[object Object]"]; baz
```
你完全可以給數組綁定key value,并且可以通過key訪問到value,也就是說你可以把數組當作一般對象使用(因為數組本身就是對象),但這不會影響到數組本身的數據(如果key是一個數字或字符串數字數組就會修改了):
```
var arr = [1, 2, 3];
arr.a = 4;
arr.length; //3
arr.a; //4
arr["3"] = 99;
//[1, 2, 3, 99]
arr.length; //4
arr[3]; //99
```
潛復制:復制基本類型,引用類型仍然在引用
深復制:復制整個對象
```
var obj1 = {};
var obj2 = {};
var obj = {
a: 2,
o1: obj1,
o2: obj2
}
var newObj = Object.assign({}, obj);
newObj.o1 === obj1; //true
newObj.o2 === obj2; //true
```
#### 屬性描述
```
var obj = {a: 2};
Object.getOwnPropertyDescriptor(obj, "a");
//{value: 2, writable: true, enumerable: true, configurable: true}
```
你也可以使用Object.defineProperty來添加或修改屬性,這個方法一般不會用到,除非修改writable(是否可以修改該屬性)、enumerable(是否可以被枚舉)、configurable(是否可以配置)。
```
Object.defineProperty(obj, "a", {writable: false});
obj.a = 3;
obj.a; //2
```
```
Object.defineProperty(obj, "a", {configurable: false});
Object.defineProperty(obj, "a", {configurable: true}); //TypeError,不可配,無法再修改了
delete obj.a;
obj.a; //2
//不可配置的obj屬性無法被刪除
```
```
var obj = {a: 1, b: 2, c: 3}
Object.defineProperty(obj, "b", {enumerable: false});
for(var key in obj) console.log(key); //a, c
```
#### 對象不變性
```
//即便使用const,對于引用類型來說僅僅是地址不變而不是內容
const obj = {a: 2, foo: [1, 2, 3]};
obj.a = 3;
obj.a; //3
obj.foo.push(4);
obj.foo; //[1, 2, 3, 4]
```
如何讓a和foo不可變呢?答案是foo始終都是可變的,而a可以做到不可變
1. writable和configurable:
```
var obj = {};
Object.defineProperty(obj, "a", {value: 2, writable: false, configurable: false});
```
2. 禁止擴展 Object.preventExtensions
```
var obj = {a: 2};
Object.preventExtensions(obj);
obj.b = 3;
obj.b; //undefined
```
3. 密封 Object.seal,相當于調用了preventExtensions并且把該對象的所有屬性都設置了configurable為false
4. 凍結 Object.freeze,相當于調用了seal并且把該對象的所有屬性都設置了writable為false
#### Getter和Setter
使用了Getter或Setter后,js就會忽略該屬性的value值以及writable是否為true,取而代之的是全部參考自getter和setter。也就是說,getter和setter會覆蓋原本的對象取值和賦值操作。因此,它們兩個最好是成對出現的,否則可能會出現意外行為。
```
var obj = {
get a() {return 2}
}
obj.a = 3;
obj.a; //2
```
```
var obj = {
get a() {return this._a]
set a(v) {this._a = v * 2}
}
obj.a = 2;
obj.a; //4
```
#### 存在性
in:屬性、原型鏈都會查找
hasOwnProperty:只會查找屬性
二者均檢查的是屬性key,而不是value
```
4 in [2, 4, 6]; //false
//key是0, 1, 2
//enumerable為false并不影響in和hasOwnProperty的結果,它僅僅是不允許枚舉
//Object.keys只會將可枚舉的屬性push
var obj = {
a: 1,
b: 2
}
Object.defineProperty(obj, 'a', {enumerable: false});
Object.keys(obj); //['b']
Object.getOwnPropertyNames(obj); //['a', 'b']
```
### 遍歷
for...in...遍歷的是key
for...of...遍歷的是value
- 你不知道的JS上
- 第一部分 第三章 函數作用域和塊作用域
- 第一部分 第四章 提升
- 第一部分 第五章 閉包
- 第二部分 第一章 關于this
- 第二部分 第二章 this全面解析
- 第二部分 第三章 對象
- 第二部分 第五章 原型
- 第二部分 第六章 行為委托
- 你不知道的JS中
- 第一部分 第二章 值
- 第一部分 第三章 原生函數
- 第一部分 第四章 強制類型轉換
- 第一部分 第五章 語法
- 第二部分 第一章 異步
- 第二部分 第三章 Promise
- 第二部分 第四章 生成器
- 第二部分 第五章 性能
- 你不知道的JS下
- 第一部分 總結
- 第二部分 第二章 語法
- 第二部分 第三章 代碼組織
- 第二部分 第四章 Promise
- 第二部分 第五章 集合
- 第二部分 第六章 新增API
- 第二部分 第七章 元編程
- 第二部分 第八章 ES6之后