# Function ###### tags: `javascript` Every JavaScript function is actually a `Function` object. This can be seen with the code `(function(){}).constructor === Function` which returns `true`. > 以下測試皆在Google Chrome進行測試。 > 我沒有要在這裡討論Hoisting和`this`的問題,so麻煩,`this`已經寫完了,hoisting有空再縮。 > 這邊的上下排序,是按照比較越常看到而且一般看到會很有問題的先寫,而不是一班學習的順序。所以那個宣告甚麼的我才會放在最後面。 ## Function可以怎麼用 ### 使用`apply`和`call`來進行呼叫 * 跟一般呼叫沒有什麼兩樣,只是這樣可以指定執行時的`this`指向。 * 呼叫`call`或`apply`,第一個參數填上要指定的`this`的指向,後面參數依序填入。 * 去看`this`的那一篇的Explicit binding。 * `call`和`apply`有空會再寫一篇他們的差別。 ```javascript= function squareArea ( width, height ) { console.log ( width ); console.log ( height ); return width * height; } console.log ( squareArea.call ( null, 2, 3 ) ); // output: 2 // 3 // 6 ``` ### 把它`new`出來 * 假設我們對一個function做`new`的動作,就相當說把這個function當作一個class來看待,那既然是一個class那就可以對它`new`出一個instance,此時這個function就會是一個建構式的角色。 * 如果這個建構式沒有回傳東西的話,那他會回傳這個新建出來的物件。 * 詳細的情形,我是打算再寫一篇關於JS的OO啦,看有沒有空。 ```javascript= function Rectangle ( width, height ) { this.width = width; this.height = height; this.area = function ( ) { return this.width * this.height; } } let square = new Rectangle ( 5, 5 ); console.log ( square.area () ); // output: 25 ``` > 於是乎,`square`會是一個`Rectangle`的物件,它有兩個property,分別是`width`和`height`,還有一個method叫做`area`。 ### 一般呼叫 就是加上小括號(`()`),它就會動了,它就會執行了,so easy。 ```javascript= function square ( number ) { return number * number; } console.log ( square ( 2 ) ); // output: 4 ``` ## Function到底可以做到那些事 * 如同,最上面所說,所有的function都是物件,一種型別為`Function`的物件。所以所有能對Object做的事情,都能對function做。 * 就把funciton當作一個_**_可執行的object就對了_**_。 ### 給他一些屬性 既然是個Object它就可以有一些屬性吧。 ```javascript= function square ( number ) { return number * number; } square.digit = "cm"; console.log ( square ( 2 ) ); // output: 4 console.log ( square ) // output: ƒ square ( number ) { return number * number; } console.log ( square.digit ); // output: "cm" ``` > 可以注意到,即使加上屬性也完全不會影響function的運作。 ### 任何地方都可以宣告 對,這很重要,因為你可以在*function裡面再宣告function*。 ```javascript= function outerFunction ( callback ) { function innerFunction ( ) { console.log ( "inner function" ); } console.log ( callback ); // output: ƒ ( ) { console.log ( "callback function" ); } callback ( ); // output: "callback function" console.log ( innerFunction ); // output: ƒ innerFunction ( ) { console.log ( "innerFunction" ); } innerFunction ( ); // output: "inner function" } outerFunction ( function ( ) { console.log ( "callback function" ); } ); ``` > 對,就是把它當一個物件用,所以可以在傳參數的時候,直接傳過去用。 > function要使用的時候,就是再加小括號`()`,就會執行了。 ### 把function指派給變數 既然function是個物件,那就是個值(value),那應該可以assign給某些變數吧。 ```javascript= function square ( number ) { return number * number; } let func = square; let obj = { func: square }; console.log ( square ); // output: ƒ square ( number ) { return number * number; } console.log ( func ); // output: ƒ square ( number ) { return number * number; } console.log ( obj ); // output: { func: ƒ square ( number ) } console.log ( obj.func ); // output: ƒ square ( number ) { return number * number; } console.log ( square ( 2 ) ); // output: 4 console.log ( func ( 2 ) ); // output: 4 console.log ( obj.func ( 2 ) ); // output: 4 ``` > 可以看到不僅可以assign給變數,使用方法跟結果完全不變 ## Function要如何宣告 宣告方式簡單來縮,有5種,但是有2個根本就沒有在用。 ### 宣告式(Function Declarations) * 最標準最普通最簡單的寫法 ```javascript= function square ( number ) { return number * number; } console.log ( square ( 2 ) ); // output: 4 console.log ( square ); // output: ƒ square ( number ) { return number * number; } ``` ### 匿名表達式(Function Expressions w/o Function Name) * 簡單來縮就是宣告一個變數,然後它的值是一個function,把function當object看就對了,所以它可以存在一個變數裡面(往下看function可以做哪些事)。 * 這個function沒有名稱喔,這就是一個匿名函式(anonymous function)。 * 建議這個變數宣告使用`const`,畢竟函數的定義不該被更改。 ```javascript= const square = function ( number ) { return number * number; } console.log ( square ( 2 ) ); // output: 4 console.log ( square ); // output: ƒ ( number ) { return number * number; } ``` > 可以注意到在後面`square`的輸出中的function是沒有名字的。 ### 具名表達式(Function Expressions w/ Function Name) * 跟上面那個一模一樣,只是function定義時多了名字,這邊的function是有名字的,只是那個名字被有啥鳥用,畢竟拿不到那個名字來做事。 * 沒有人在用這個啦! ```javascript= const square = function squareRealName ( number ) { return number * number; } console.log ( square ( 2 ) // output: 4 console.log ( square ); // output: ƒ squareRealName ( number ) { return number * number; } console.log ( squareRealName ); // ReferenceError: squareRealName is not defined ``` ### 建構子式(Function Constructor) * 所以我前面有縮,把function當object來看待,所以,它也有它的Constructor。 * 所有JavaScipt的funciton都是`Function`型態(看看最上面一句話),所以你可以透過`new Function ( )`,把它`new`出來。 * 建立出來的function基本上就跟前面那個(具名表達式)的結果一樣,這個function的名字叫做anonymous,一樣沒啥鳥用。 * 沒有人在用這個啦! ```javascript= const square = Function ( "number", "return number * number" ); console.log ( square ( 2 ) ); // ooutput: 4 console.log ( square ); // output: ƒ anonymous(number) {return number * number} ``` > 可以看到那個被new出來的function是有名字的就叫做`anonymous`。 ### 箭頭函式(Arrow Function) 去看ES6新功能的那一篇啦 ## 參考資料 * 函數定義 (Function Definition) 的 100 種寫法:https://ithelp.ithome.com.tw/articles/10207740 * Function:https://ithelp.ithome.com.tw/articles/10194538 * Function: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up