「Javascript」new關鍵字創建對象底層原理

我們都知道,new關鍵字可以在js裡可以產生一個新對象,但是它到底是怎麼產生的對象呢?現在我們就來探秘new的底層原理

//人類構造函數
function People(){
}
People.prototype.index = 1; //在原型上綁定一個index屬性,值為1
var p1 = new People(); //我們都知道使用new可以產生一個對象,但是到底是怎麼產生出來的對象,想必很多同學都不清楚

每當我們使用new產生對象的時候,底層進行了很多操作,簡單描述可分為以下2步

1. 實例化一個空對象(Object),繼承構造函數的原型(prototype)

2. 已當前Object為上下文,執行new後面的函數,並改變this指向

分步解析

new People() = {
//1 var obj = new Object();
//2 obj.__proto__ = People.prototype;
//3 People.call(obj);
}

(1)第1行:創建一個空對象obj;

(2)第2行:把obj的proto指向People的原型對象prototype

(3)第3行:在當前對象上下文內執行People函數,並改變this指向,指向此對象本身

那麼屬性是在什麼時候綁定上去的呢?我們可以看到People原型的index屬性並沒有賦值過給obj,但是為什麼obj有index這個屬性呢?

function People(){
}
People.prototype.index = 1;
var p1 = new People();
console.log(p1.index); //打印1

其實,當我們把obj的proto指向People的原型對象時,就產生了obj的原型鏈

obj -> People.prototype -> Object.prototype -> null

當我們在找obj.index屬性時,它會先找自身的index屬性,如果找不到,則會順著原型鏈向上找,這時會找到People.prototype.index,所以最後打印1。

如果在People的原型上也找不到,那麼它會繼續往上去找,直到最後找到null。

function People(){
}
People.address = "ChengDu";
People.prototype.index = 1;
var p1 = new People();
console.log(p1.index); //1
console.log(p1.address); //undefined

為什麼address屬性獲取不到呢?仔細看,People這個構造函數其實並不在原型鏈上,address屬性綁定的實在People函數本身,而沒有在People.prototype上!

如果你能看理解上面的代碼,說明你已經對這塊已經比較熟了,那麼我們再往下看!

1 function People(){ 

2
3 }
4 People.prototype.index = 1;
5 var p1 = new People();
6 People.prototype.index = 20;
7 console.log(p1.index); //現在p1.index等於多少呢?1還是20?

如果你的答案是20,你已經掌握了剛才的內容。

(1) 第5行,產生p1

(2) 第6行,修改People原型的index屬性,index現在變為了20

(3)第7行,訪問p1.index,p1因為沒有index屬性,所以順著原型鏈找到People.prototype.index,打印20

我們再來看一個變形示例

1 function People(){
2
3 }
4 People.prototype.index = 1;
5 var p1 = new People();
6 p1.index = 30;
7 console.log(p1.index); //現在p1.index是多少?
8 console.log(People.prototype.index) //1還是30?

答案,p1.index = 30; People.prototype.index = 1; 如果你已經正確!恭喜,你已經熟練掌握本章內容,可以跳過以下部分!

(1) 第5行,產生p1

(2) 第6行,給p1綁定index屬性,並賦值30

(3)第7行,訪問p1.index,找屬性時,會優先找自己身上,如果沒有,才會順著原型鏈向上找,此時自身已有index屬性,所以打印30

(4) 第8行,訪問People.prototype.index,因為People原型的index屬性並沒被修改過,所以打印的值還是1


分享到:


相關文章: