2018-10-17

關於 javascript 的 IIFE

IIFE:Immediately-invoked Function Expressions,是指一個被(瀏覽器)定義完後就馬上執行的函式(或叫方法)的表達方式。

先說明一下,函數的表達有所謂的函數宣告和函數運算式的常用方式;
函數宣告
<script>
a(1);
function a(x) {
  console.log( 'x = ' + x );
}
a(2);
/*
* console output:
* x = 1 ( a(1) 呼叫 a(x) function 運行 console.log( 'x = ' + x ) )
* x = 2 ( a(2) 呼叫 a(x) function 運行 console.log( 'x = ' + x ) )
*/
</script>

函數運算式
<script>
a(1);
var a = function(x) {
  console.log( 'x = ' + x );
}
a(2);
/*
* console output:
* TypeError: a is not a function; ( 不能在函數運算式之前來呼叫函式 )
* x = 2 ( a(2) 呼叫 a(x) function 運行 console.log( 'x = ' + x ) )
*/
</script>
兩種的差別,以我的看法,我覺得所謂函數運算式比較像 object 或變數的定義方式…而 IIFE 好像就沒有函數運算式的定義方式,因為 IIFE 會直接運行,所以會把 IIFE 的結果直接給予定義,然後會依其結果而定義成變數或 object 。
另外,函數宣告和函數運算式在 ECMAscript 的定義上是有其標準的,譬如函數宣告被放在巢狀結構範圍中就不能算是函數宣告,而是函數運算式。



IIFE 的寫法 ① :
<script>
/* error, not Function Expressions */
function(x) {
  console.log( 'x = ' + x);
}(1);
/*
* console output:
*   Uncaught SyntaxError: Unexpected token (; (非 function 表達式)
*/

/* a */
(function(x) {
  console.log( 'x = ' + x);
}(1));
/*
* console output:
* x = 1 (IIFE 運行 console.log( 'x = ' + x ))
*/

/* b */
(function(x) {
  console.log( 'x = ' + x );
})(1);
/*
* console output:
* x = 1 (IIFE 運行 console.log( 'x = ' + x ))
*/

/* c */
var c = function(x) {
  console.log( 'x = ' + x );
};
console.log( 'c(1) = ' + c(1) );
console.log( 'c = ' + c );
/*
* console output:
* x = 1 ( c(1) 呼叫 function,執行 console.log( 'x = ' + x ) )
* c(1) = undefined ( 因為 function 沒有 return )
* 
* ( console.log( 'c = ' + c' ) 的結果如下)
* c = function(x) {
*   console.log( 'x = ' + x);
* }
*/

/* d */
var d = function(x) {
  console.log( 'x = ' + x );
}(1);
console.log( 'd(1) = ' + d(1) );
console.log( 'd = ' + d );
/*
* console output:
* x = 1 ( IIFE 運行 console.log( 'x = ' + x ) )
* TypeError: d is not a function; ( 因為 d 是存放 IIFE 運行後的結果,所以 d 是變數而不是函式 )
* d = undefined ( 因為 IIFE 沒有 return )
*/

/* e */
var e = function(x) {
  console.log( 'x = ' + x );
  return x;
}(1);
console.log( 'e(1) = ' + e(1) );
console.log( 'e = ' + e );
/*
* console output:
* x = 1 ( IIFE 運行 console.log( 'x = ' + x )
* TypeError: e is not a function; ( 因為 e 是存放 IIFE 運行後的結果,所以 e 是變數而不是函式 )
* e = 1 ( e 存放 IIFE 運行結果,且 IIFE 有 return x ,所以 e = 1)
*/
</script>

IIFE 的寫法 ②:
<script>
((x) => {
  console.log( 'x = ' + x);
})(1);

((x) => {
  console.log( `x = ${x}` ); // Template Strings:用 `` (back-tick:反引號或叫重音符號)包住內含變數、函式或運算式的格式化文字時可以這樣用,且還可以有斷行
})(2);

var a = ((x) => {
  console.log( 'x = ' + x );
  return x;
})(3);
//console.log( 'a(4) = ' + a(4) );
console.log( 'a = ' + a );
</script>

沒有留言: