# Constructor Function Constructor? # 函式建構器(Function Constructor) function constructor 的功能主要在於建立一個function,方法如下: ```javascript= const multiply = new Function("x", "y", "return x * y"); ``` 這段程式碼意思是建立一個function multiply包含x, y兩個參數,回傳x + y ![image](https://hackmd.io/_uploads/BJ-u1cd-0.png) ![image](https://hackmd.io/_uploads/SyiRCDPbC.png) 函式建構器是動態生成function的方法,也相較於eval()解決環境污染問題,由於動態生成,所以可以達到下面的效果: ```javascript= function test(){ return `"'1' + '2'"`; } const test1 = new Function(`return ${test()}`); console.log(test()); console.log(test1()); ``` 先靜態建立function test() 在動態建立test1,回傳值抓取test()的值 ![image](https://hackmd.io/_uploads/ByqcrK_ZC.png) test()回傳的是引號``字串"'1' + '2'" 而test1()回傳引號""內的字串'1' + '2' 有看出不一樣嗎?靜態單純回傳所有內容,動態會辨識字串裡的內容 還是不懂?把最外面引號``拿掉看看 ```javascript= function test(){ return "'1' + '2'"; } ``` ![image](https://hackmd.io/_uploads/ryq3UFuZA.png) test()回傳字串引號內的字串'1' + '2' test1()回傳字串12,也就是字串'1'跟'2'的相加 靜態的test()回傳雙引號""裡面的內容(字串) 動態的test1()則是執行引號""裡面的內容並回傳 現在改成: ```javascript= function test(){ return "4 * 6" } ``` ![image](https://hackmd.io/_uploads/r1NWkquW0.png) 結果就是靜態的test()回傳字串4 * 6 動態test1()回傳引號內的運算結果 [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function) # 建構器函式(Constructor Function) 通常是用創造物件的工具,可以快速產生結構類似的物件 使用方法如下: 定義一個建構函式Constructor Function ```javascript= function MBTI(name, MBTI, gender){ this.name = name; this.MBTI = MBTI; this.gender = gender; } ``` 這邊我做了一個可以創造有**名字**、**十六型人格**跟**性別**的物件 接者把它拿來用! ```javascript= let Jeremy = new MBTI("Jeremy", "INFJ", "male"); let Watson = new MBTI("Watson", "ENFJ", "male"); let Fang = new MBTI("Fang", "ISFJ", "female"); let Jami = new MBTI("Jami", "INFP", "female"); let Tangerine = new MBTI("Tangerine", "ISFJ", "female"); ``` 如此一來我就建立了五個新的物件,裡面包含我們的十六行人格 拿三個出來看看: ```javascript= console.log(Jeremy); console.log(Fang); console.log(Tangerine); ``` ![image](https://hackmd.io/_uploads/BkFdZjuZC.png) 確實有這三個MBTI的物件~ [參考資料](https://javascript.alphacamp.co/constructor-function.html) # 建構函式與prototype的應用 這邊我想把每個物件裡的內容組成句子,函式如下: ```javascript= const title = (this.gender == "male") ? "his" : "her"; return `${this.name}, ${title} MBTI is ${this.MBTI}.` ``` 直覺上會想把他也加進建構函式裡面: ```javascript= function MBTI(name, MBTI, gender){ this.name = name; this.MBTI = MBTI; this.gender = gender; const title = (this.gender == "male") ? "his" : "her"; this.describe = function(){ return `${this.name}, ${title} MBTI is ${this.MBTI}.` } } ``` 執行出來會長這樣: ![image](https://hackmd.io/_uploads/r1Djf6_bC.png) 執行裡面的function describe: ![image](https://hackmd.io/_uploads/B1PZQaub0.png) 可以得到我想要的: ![image](https://hackmd.io/_uploads/H10mXpuWA.png) 此時會有佔據過多記憶體的問題,在我建構每個MBTI時,都會建立describe這個function,有1000個物件就存1000個function,這時候可以思考其實每個function都長一樣,可以共用,prototype這個屬性就幫我們實現了~ 在MBTI的prototype裡面加上一個function describe: ```javascript= MBTI.prototype.describe = function(){ const title = (this.gender == "male") ? "his" : "her"; return `${this.name}, ${title} MBTI is ${this.MBTI}.` } ``` 此時describe這個function就是所有MBTI物件的共用方法 Chris說現在寫法是這樣: :100: ```javascript= class MBTI { constructor(name, MBTI, gender){ this.name = name; this.MBTI = MBTI; this.gender = gender; } describe (){ const title = (this.gender == "male") ? "his" : "her"; return `${this.name}, ${title} MBTI is ${this.MBTI}.` } } ``` ~~上面舊的寫法不直覺不好記~~ :heavy_check_mark: 並沒有新舊,上面是原本寫法,下面是簡寫,寫可以寫下面加速開發,但理解要理解上面。