### [[Prototype]]
當你試圖引用對象的時候,就會觸發[[Get]]操作,當對象本身不含有該屬性時就會查找[[Prototype]]鏈,如果鏈沒有找到該屬性并且鏈不為空,則會繼續順延[[Prototype]]繼續查找下去。
for...in...會枚舉出所有可enumerable的屬性,包括原型鏈上的。
而...in...操作符來檢查屬性時也會查找原型鏈(無論屬性是否可枚舉)。
#### 屏蔽
所謂屏蔽,就是原型鏈上有foo屬性,而對象本身沒有該屬性,當執行obj.foo操作時會為該對象添加foo屬性,原型鏈的foo會被遮蔽。
1. 如果原型鏈上存在foo屬性,且可讀,則obj.foo操作會直接在obj上添加foo屬性。
2. 如果原型鏈上存在foo屬性,且不可讀,則該操作會失敗,foo屬性不會被添加。
3. 如果原型鏈上存在foo屬性,且設置了setter,則該操作會觸發setter。foo不會被添加,也不會重新定義這個setter。
隱示屏蔽
```
var obj1 = {a: 2};
var obj2 = Object.create(obj1);
obj1.a; //2
obj2.a; //2
obj2.hasOwnProperty('a'); //false
obj2.a++;
obj1.a; //2
obj2.a; //3
obj2.hasOwnProperty('a'); //true
//obj2.a++實際上就是obj2.a = obj2.a + 1,創建了一個新的自身的a,屏蔽了原型的
```
### 類
new操作符并不是創建新的實例,而是讓“新實例”的原型指向函數的prototype。
```
function Foo() {};
var a = new Foo();
Object.getPrototypeOf(a) === Foo.proptotype; //true
```
#### 構造函數與調用
Foo與其他函數沒有任何區別,當使用new調用時會執行“構造函數調用”。
```
function Foo() {console.log(123)};
var a = new Foo();
//123
console.log(a); //{}
```
所以,js中的構造函數,其實就是帶new的普通函數罷了。
回顧構造函數,.constructor并不是代表“由誰構造”,它只是委托。
```
//函數自帶constructor
Foo.prototype.constructor == Foo; //true
var a = new Foo();
//a沒有constructor,此時會查找原型鏈,Foo的原型上有constructor,返回
a.constructor === Foo; //true
Foo.prototype = {};
var b = new Foo();
//現在,Foo.prototype已經沒有了constructor,只能繼續向上查找,直到Object(Object.prototype.constructor)
b.constructor === Foo; //false
b.constructor === Object; //true
```
### 原型繼承
```
//創建一個新的Bar.prototype對象并指向Foo.prototype,舊的Bar.prototype會被拋棄。修改Bar.prototype不會影響Foo.prototype
Bar.prototype = Object.create(Foo.prototype);
//直接指向Foo.prototype,修改Bar.prototype會影響Foo.prototype
Bar.prototype = Foo.prototype;
//另一種實用的方法,es6的api,直接修改現有的Bar.prototype并且不影響Foo.prototype
Object.setPrototypeOf(Bar.prototype, Foo.prototype)
```
`var b = Object.create(a)`,如果a是對象的話會創建新的b.prototype并將其指向a,如果a是函數的話則b.prototype將會指向a.prototype。
```
function A(){this.name = 1};
var b = Object.create(A); //b是一個函數
b.prototype.constructor === A; //true
var A = {a: 1};
var b = Object.create(A);
b.prototype; //undefined
b.__proto__ === A; //true
```
- 你不知道的JS上
- 第一部分 第三章 函數作用域和塊作用域
- 第一部分 第四章 提升
- 第一部分 第五章 閉包
- 第二部分 第一章 關于this
- 第二部分 第二章 this全面解析
- 第二部分 第三章 對象
- 第二部分 第五章 原型
- 第二部分 第六章 行為委托
- 你不知道的JS中
- 第一部分 第二章 值
- 第一部分 第三章 原生函數
- 第一部分 第四章 強制類型轉換
- 第一部分 第五章 語法
- 第二部分 第一章 異步
- 第二部分 第三章 Promise
- 第二部分 第四章 生成器
- 第二部分 第五章 性能
- 你不知道的JS下
- 第一部分 總結
- 第二部分 第二章 語法
- 第二部分 第三章 代碼組織
- 第二部分 第四章 Promise
- 第二部分 第五章 集合
- 第二部分 第六章 新增API
- 第二部分 第七章 元編程
- 第二部分 第八章 ES6之后