[JS奇怪的世界]No.50 函數建構子、「new」與 JavaScript 的歷史
前言
前面我們已經瞭解許多物件、原型繼承、原型鏈和物件屬性及方法,接下將更深入討論建立物件。
「new」
前面我們已經有講過幾種建立物件的方式,其中一個是物件實體語法。
1 | var jack = { |
而其實還有別的物件建立方式。
1 | var jack = new Person(); |
那為什麼會有 new
?,這主要與 JavaScript 的誕生有關係,一個語言若都沒有人使用就代表著死亡,所以當初 JavaScript 會叫 JavaScript 就是希望可以吸引 Java 開發者,而 Java 開發者習慣使用 new
的關鍵字來定義物件等等,所以當 Java 開發者看到這樣寫會感覺比較親切,但是使用這種方式來建立物件有些許問題,但是我們還是需要瞭解,因為許多專案及原始碼都會有它的存在。
下面將用課堂的範例來做一點好玩的事情。
1 | function Person() { |
我們發現 john 變成一個物件了,但是這邊我們要記得一件事情,我們只是在利用一些方法在 JavaScript 中建立物件,那為了建立物件我們必須給它屬性和方法,然後建立原型,而這是為了讓我們看更清楚而做的,所以接下來將使用比較正確的方式來增加屬性和方法、設定原型。
那 new
其實是一個運算子,為什麼這樣講呢?讓我們翻一下先前的文件>MDN 的文件 (在下方一點地方)
上面的例子中 new
會改變 this
指向的東西,this
指向到一個空的物件,而 new
建立了一個新物件,然後呼叫了 Person()
,所以現在 this
變數指向 new
創造的新的空物件的記憶體位置。
所以當我們打 .firstname
和 .lastname
就會增加到空物件上,就像這樣。
1 | var john = {}; |
而在 JavaScript 中會回傳 new 運算子建立的物件,這會建立一個新物件,而成為物件的一部分也會回傳東西,所以我們試著這樣嘗試看看。
1 | function Person() { |
由此可知,new 運算子會對這個函數呼叫,然後在回傳裡面的東西變成物件。
那如果 this
我們什麼都不對他做的話,他將會回傳本身。
1 | function Person() { |
但是如果我們本身若對函數回傳的話,就會變成只回傳那個資料。
1 | function Person() { |
如果沒有回傳時,JavaScript 就會改找我們設定 this
的變數。
所以我們可以從這邊知道,我們可以透過函數來建構物件,而這叫做函數建構子。
那我們可以依照 函數建構子 來做一點進階的作法,假設今天 firstname
及 lastname
是改由我們自己傳入呢?
1 | function Person(first, last) { |
所以我們可以利用函數參數的特性來傳入資料進而改變 firstname
及 lastname
。
簡單來講 new 運算子可以做出新物件,函數建構子是被用來增加新物件的屬性和方法