函數是JavaScript很是重要的一部分,它被稱爲第一等公民,能夠看出它的地位是何等尊貴何等重要。根據我一向的做風,會深刻原理性的東西,那這篇文章主要來挖掘函數聲明與函數表達式相關知識。javascript
在JavaScript中定義一個函數有四種方式java
function 函數名(參數){ 要執行的代碼 }
- 函數名(參數)
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(參數){ 要執行的代碼 }
- 函數名(參數)
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('以被賦值的形式出現也是一個函數表達式'); };
函數聲明必須帶有標識符(函數名稱),函數表達式則能夠省略app
//一、名字 //函數聲明必需帶名字 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 ); //二、預解析 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出如今行首函數
- 用括號把function主體括起來,轉成表達式。後面加括號運行
//小括號裏只能放表達式 ( if(true){ console.log(1); } )//報錯,括號裏不能放語句 (1); (1+2); ([1]); ({}); function fn(){ console.log('函數聲明執行'); }(1); //符合語法,可是函數不會執行 //想要執行就必需把函數聲明轉成表達式,而小括號裏只能放表達式,利用這個特徵把函數放在一對括號裏,再加一對括號就能執行 (function fn(){ console.log('函數聲明執行'); })(); //或者這樣也能夠執行 (function fn(){ console.log('函數聲明執行'); }());
只要把函數聲明轉成表達式,再加上括號就能夠聲明。那就有不少稀奇古怪的方式來執行函數code
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運算符變成表達式');