先簡單介紹函數陳述式和函數表示式
一開始函式會被放進記憶體,函式需要名稱
function greet(name){
console.log('Hello'+ name);
}
//呼叫
greet('Jhon');
可以用匿名函式,一開始函式不會被放進記憶體,而是在執行這一行程式碼時,JS才會立刻創造函數物件
var greetFunc = function(name){
console.log('Hello'+ name);
}
//呼叫
greetFunc('Jhon');
以上2者執行結果
在創造函數時立刻呼叫函數
這種寫法的函式如同其他函式,也可以擁有閉包
var greetFunc = function(name){
console.log('Hello'+ name);
}();
例1:
var greetFunc = function(name){
return 'Hello'+ name;
};
console.log(greeting('Jhon'));
執行結果
例2:
加上()呼叫,()會指向greeting
var greeting = function(name){
return 'Hello'+ name;
}();
console.log(greeting);
執行結果
例3:
在括號裡傳入參數'John'
var greeting = function(name){
return 'Hello'+ name;
}('John');
console.log(greeting);
執行結果
要注意這裡的console.log(greeting); 的 greeting是字串,不是函數
console.log(greeting());
如果試著呼叫greeting()會得到錯誤,因為執行到return時是字串,也就是greeting的值,不是函數。
//數值
3;
//字串
"string";
//物件
{name:'Jhon'};
//函數,讓陳述式變表示式,可以加括號,讓第一個字不是function
(function(name){
return 'Hello'+ name;
});
function這個字在一行的最前面,或是接在分號之後,所以JS預期這是一個函數陳述句,它不可以是匿名的,不然會出錯。
讓陳述式變表示式,可以加括號,讓第一個字不是function。
陳述式不會使用(),()會使用在表示式,在()裡的一定是表示式。
括號()放裡面或外面功能都一樣
(function(){...}());
(function(){...})();
例:
(function(){
var greeting = 'Hello';
console.log(greeting + ' ' + name);
}());
例:
加入參數
var firstname = 'John';
(function(){
var greeting = 'Inside IIFE : Hello';
console.log(greeting + ' ' + name);
}(firstname));
執行結果
程式碼包在IIFE裡,相同的名稱不會和全域物件衝突,因為它們會有自己的執行環境,不同的記憶體位置,函式裡面宣告的變數不會接觸到全域環境。
當你創造一些可重複利用的東西時,可以用IIFE來確保程式不會和其他程式衝突,就不會不小心放到全域物件,但要記得傳入參數,因為物件是傳參考(pass by reference)
所以如果我想要取用全域物件 ,要把它傳入我的函數,想要可以在任何地方取用它,故意讓它黏在全域物件上(?)
所以我要傳入全域變數的參考給IIFE
(function(global, name){
var greeting = 'Hello';
global.greeting = 'Hello';
console.log(greeting + ' ' + name);
}(window, 'John'));
console.log(greeting);