函數聲明與函數表達式
阿新 • • 發佈:2018-09-23
裏的 doc typeof 成語 先來 出現 主動 set 有一個 函數是JavaScript非常重要的一部分,它被稱為第一等公民,可以看出它的地位是何等尊貴何等重要。根據我一貫的作風,會深入原理性的東西,那這篇文章主要來挖掘函數聲明與函數表達式相關知識。
在JavaScript中定義一個函數有四種方式
- 函數聲明
- 函數表達式
- ES6裏箭頭函數
- new Function()
函數聲明
語法
function 函數名(參數){
要執行的代碼
}
調用
- 函數名(參數)
- 函數名.call(函數名,參數)
- 函數名.apply(函數名,[參數])
- new 函數名(參數)
- 定時器
- 把函數聲明變成函數表達式再調用
- ES6裏的模版字符串
function fn(text){ console.log(text); } fn(‘直接調用‘); fn.call(fn,‘用call調用‘); fn.apply(fn,[‘用apply調用‘]); new fn(‘用new調用‘); setTimeout(fn(‘用定時器調用‘)); (function fn(text){ console.log(text); })(‘轉成函數表達式後調用‘); fn`用模版字符串調用`; //ES6裏語法
函數表達式
語法
var/let/const 變量=function(參數){
要執行的代碼
}
調用
- 函數名(參數)
- 函數名.call(函數名,參數)
- 函數名.apply(函數名,[參數])
- new 函數名(參數)
- 直接在後面加上一對小括號
- 定時器
- ES6裏的模版字符串
- 以被賦值的形式出現(根據具體形式調用)
const fn=function(text){ console.log(text); }; fn(‘直接調用‘); fn.call(fn,‘用call調用‘); fn.apply(fn,[‘用apply調用‘]); new fn(‘用new調用‘); const fn2=function(text){ console.log(text); }(‘直接在後面加小括號調用‘); setTimeout(fn(‘用定時器調用‘)); fn`用模版字符串調用`; document.onclick=function(){ console.log(‘以被賦值的形式出現也是一個函數表達式‘); };
函數聲明與函數表達式的區別
- 函數聲明必須帶有標識符(函數名稱),函數表達式則可以省略
- 表達式裏的名字不能在函數外面用,只能在函數內部用
- 函數有一個name屬性,指向緊跟在function關鍵字之後的那個函數名。如果函數表達式沒有名字,那name屬性指向變量名
- 函數聲明會被預解析,函數表達式不會
//1、名字 //函數聲明必需帶名字 function fn(){}; //function(){}; //報錯,沒有名字 //函數表達式可以沒有名字 let fn1=function(){}; (function(){}); !function(){}; //表達式名字的作用 let fn2=function newFn(){ console.log(newFn); //可以在這裏面用。有一個作用就是在這裏用遞歸 }; fn2(); //newFn(); //報錯,不能在外面用 //name屬性 console.log( fn.name, //fn fn1.name, //fn1 表達式沒有名字,name屬性指向表達式變量名 fn2.name //newFn ); //2、預解析 fn3(); function fn3(){ console.log(‘fn3‘); } //fn4(); //報錯,不會被預解析 let fn4=function(){ console.log(‘fn4‘); }
自執行函數
自執行函數也叫立即調用的函數表達式(IIFE)。它的作用為我們不用主動地去調用函數,它會自己調用,對於做模塊化、處理組件是非常有用的。
首先來看一個問題,調用函數最簡單的方法就是加一對小括號,那我在函數聲明的末尾加一對括號後,這個函數能否調用呢?
function fn(){
console.log(1);
}(); //報錯
const fn1=function(){
console.log(‘表達式執行‘);
}(); //執行函數
函數聲明不能直接調用的原因
- 小括號裏只能放表達式,不能放語句
- function關鍵字即可以當作語句,也可以當作表達式。但js規定function關鍵字出現在行首,一律解釋成語句
解決方法:不要讓function出現在行首
- 用括號把function主體括起來,轉成表達式。後面加括號運行
- 借助運算符(new + - ! ~ typeof , && ||...)
因為運算符會把表達式執行,執行後得出結果了才能運算
//小括號裏只能放表達式
(
if(true){
console.log(1);
}
)//報錯,括號裏不能放語句
(1);
(1+2);
([1]);
({});
function fn(){
console.log(‘函數聲明執行‘);
}(1); //符合語法,但是函數不會執行
//想要執行就必需把函數聲明轉成表達式,而小括號裏只能放表達式,利用這個特征把函數放在一對括號裏,再加一對括號就能執行
(function fn(){
console.log(‘函數聲明執行‘);
})();
//或者這樣也可以執行
(function fn(){
console.log(‘函數聲明執行‘);
}());
只要把函數聲明轉成表達式,再加上括號就可以聲明。那就有很多稀奇古怪的方式來執行函數
0+function(text){
console.log(text);
}(‘與數字相加變成表達式‘);
true&&function(text){
console.log(text);
}(‘利用邏輯運算符變成表達式‘);
false||function(text){
console.log(text);
}(‘利用邏輯運算符變成表達式‘);
0,function(text){
console.log(text);
}(‘利用逗號運算符變成表達式‘);
//二進制位取反運算符
~function(text){
console.log(text);
}(‘前面加上+-!~變成表達式‘);
new function(text){
console.log(text);
}(‘利用new運算符變成表達式‘);
typeof function(text){
console.log(text);
}(‘利用typeof運算符變成表達式‘);
函數聲明與函數表達式