一開始在寫初學筆記的時候,我們就有提到advanced object中的function factory的概念,也就是利用函數做出其他程式語言中class的效果,今天先來介紹JS 中的Constructor Function,接著會補充JS在後續的版本新增的class關鍵字,最後會解說一下在JS中非常重要的原型鍊概念。
const students = (name,id,gender) => { return { name, id, gender } } const danny = students("danny",9831032,'male') console.log(danny) // { name: 'danny', id: 9831032, gender: 'male' }
Constructor Function
先看一下以下的程式碼。
var Vegetable = function(name){ this.name = name; } var carrot = new Vegetable ('carrot'); console.log(carrot.name) // carrot
這是constructor function的基本概念,其實就是創造物件的函式。
可以注意到其中並沒有return任何東西,這是建構式函式的基本特點。
依序解釋一下剛剛的程式碼中發生了什麼事情。
1.建立一個名為Vegetable的constructor ,裡面包含著name這個特性,可以想成一個標準範本。
2.利用new關鍵字 以及 constructor 建立一個名為 carrot的實例(instance),也就是利用 constructor 建立的東西。
使用new關鍵字的時候,其實依序發生了以下的事情
2.1 建立一個空物件
2.2 啟用Vegetable函數
2.3 Vegetable 內的this指向到剛剛的空物件中
當建立完實例後,可以利用以下的方法去找出最初的建構子
console.log(carrot.constructor.name) // Vegetable
Class
上述的例子在ES6之後可以藉由class關鍵字完成,值得注意的是JS 中的class與其他程式語言的class有本質上的區別,光是使用class關鍵字並不能製造出有完整功能的類別,最好還是當做一個全新的概念學習。
class Vegetable { constructor(name){ this.name = name } } var carrot = new Vegetable ('carrot'); console.log(carrot.name) //carrot
在這個情境中,class宣告了一個新函數Vegetable ,在新函數中同時加入了 constructor ,最終利用new 激活(invoked)而創造一個新物件,兩種方法都會達成一樣的效果。
原型鍊(prototype)
這大概是接觸最久,但一直沒去釐清的重要概念之一了。
之前就有提過,其實在JS中,所有東西都是物件,舉個例子來說
const name = 'danny' console.log(Object.getPrototypeOf(name)) // [String : ''] console.log(Object.getPrototypeOf(Object.getPrototypeOf(name))) // {}
上面的範例中我宣告了一個字串name,接著利用Object.getPrototypeOf(name)找出該物件的原型,為求精確在下一行再往上去追尋它的原型。
今天當我使用name.length,實際上是發生了以下的事情
先去尋找name中是否有 length這個屬性或方法,若沒有則繼續往上找它的原型是否具有該方法,這個例子中就會找到String中的.length屬性,若還是找不到則再往上追尋,直到找到null為止,系統才會回傳name不具有該方法。 聽起來有點複雜,實際上跑一次就會比較了解了!