[JavaScriptWeird]No.44 函數建構子「new」

前言

至此我們已經了解物件和原型、繼承、原型鏈、物件屬性、方法等等,現在該更深入的討論建立物件。之前建立物件的方式都是使用物件實體語法建立的,然而有另一種方法可以建立物件,這是本篇要討論的內容。

函數建構子「new」

一個正常的函式用來建立物件,當在呼叫函式前面放了 new 關鍵字時,在執行階段的創造階段被產生的 this 變數會指向新的空物件,當函式結束執行時,該物件會被函式自動回傳。

看看例子:

1
2
3
4
5
function person(){  
this.firstName = 'Doe';
this.lastName = 'John';
}
var john = new person();

像這樣建立了一個 person 函式,接著用 new 關鍵字建立物件,並且輸出結果觀察。

居然一個物件就建立好了,我們來看看發生了什麼事。

在這個例子,我們只是用不同的方式在 JavaScript 中建立物件,為了建立物件,我們需要給這個物件屬性和方法以及設定原型,在前面幾篇文章我們都用錯誤的方式在設定原型,那只是為了好理解原型是如何運作的。

new 是個運算子,記得先前幾篇提到的運算子優先性嗎?

可以在裡面找到 new 這個關鍵字。當使用 new 時一個空物件被建立,就好比直接用物件實體語法這樣寫:

1
var a = {};

接著運算子 new 呼叫函式 person ,當函式被呼叫時執行環境會產生 this ,然而 new 會改變 this 的指向到產生的空物件,於是我們寫的程式屬性被執行後, firstNamelastName 屬性被增加到空物件上。

使用 new 運算子的函式並不會回傳值,因為 JavaScript 會回傳被 new 運算子建立的物件,並且會呼叫這個函式:

1
2
3
4
5
6
7
function person(){  
this.firstName = 'Doe';
this.lastName = 'John';
console.log('我被呼叫了');
}
var john = new person();
console.log(john);

如果不作任何事情,這個 this 會是什麼?

1
2
3
4
5
6
7
function person(){  
console.log(this);
this.firstName = 'Doe';
this.lastName = 'John';
console.log('我被呼叫了');
}
var john = new person()

此時的 this 會指向 person 空物件,後來我們增加屬性,於是空物件內多了屬性。

我們說使用 new 運算子的函式並不會回傳值,如果主動回傳值的話會發生什麼事情呢?

1
2
3
4
5
6
7
8
9
function person(){  
console.log(this);
this.firstName = 'Doe';
this.lastName = 'John';
console.log('我被呼叫了');
return { greeting: '你好' }
}
var john = new person();
console.log(john);

於是 new 運算子便會回傳我們寫的 return 內容,但如果不回傳任何東西,JavaScript 會知道要建立一個新物件。

使用 new 運算子也能一次建立多個同樣的屬性、方法的物件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function person(){  
console.log(this);
this.firstName = 'Doe';
this.lastName = 'John';
console.log('我被呼叫了');
}
var john = new person();
var joan = new person();
var jim = new person();

console.log(john);
console.log(joan);
console.log(jim);

![](https://cdn-images-1.medium.com/max/800/1*YcF93DU_6M0uWco5YHRCFQ.png)

像這樣,即可建立多個相同屬性方法的物件,但可以再做一些調整

1
2
3
4
5
6
7
8
9
10
11
12
13
function person(firstName, lastName){  
console.log(this);
this.firstName = firstName;
this.lastName = lastName;
console.log('我被呼叫了');
}
var john = new person('Doe', 'john');
var joan = new person('Mar', 'joan');
var jim = new person('TTT', 'jim');

console.log(john);
console.log(joan);
console.log(jim);

new 後面接的是函式所以可以傳入參數,因此可以設定不同的 firstNamelastName

0%