JS函數有兩種命名方式
1、聲明式
聲明式會導致函數提升,function會被解釋器優先編譯。即我們用聲明式寫函數,可以在任何區域聲明,不會影響我們調用。
function XXX(){}
2、函數表達式
函數表達式我們經常使用,而函數表達式中的function則不會出現函數提升。而是JS解釋器逐行解釋,到了這一句才會解釋。
因此如果調用在函數表達式之前,則會調用失敗。
var k = function(){}
fn1(); function fn1(){}//可以正常調用 fn2(); var fn2 = function(){}//無法調用
產生的原因
現在進入正題,對函數表達式加上(),是可以直接調用的
但是如果是對聲明式的后部加上()則是會被編譯器忽略。
var fn2 = function(){}();//對,就是這樣 function fn1(){}();//會被忽略
而平常的function(){}則是一種聲明式,如果加上()括號后,則會被編譯器認為是函數表達式,(加上+-號都可以),從而可以用()來直接調用
(function fn1(){})();
自執行匿名函數
自執行函數,即定義和調用合為一體。
我們創建了一個匿名的函數,並立即執行它,由於外部無法引用它內部的變量,因此在執行完后很快就會被釋放,關鍵是這種機制不會污染全局對象。
- 常見格式:
(function() { /* code */ })();
- 解釋:包圍函數(function(){})的第一對括號向腳本返回未命名的函數,隨后一對空括號立即執行返回的未命名函數,括號內為匿名函數的參數。
- 作用:可以用它創建命名空間,只要把自己所有的代碼都寫在這個特殊的函數包裝內,那么外部就不能訪問,除非你允許(變量前加上window,這樣該函數或變量就成為全局)。
各JavaScript庫的代碼也基本是這種組織形式。
總結一下,執行函數的作用主要為 匿名 和 自動執行,代碼在被解釋時就已經在運行了。
// 下面2個括弧()都會立即執行 (function () { //我是匿名方式1----推薦使用這個----這種經常用來構建沙箱模式 } ()) (function () { //我是匿名方式2 })() // 由於括弧()和JS的&&,異或,逗號等操作符是在函數表達式和函數聲明上消除歧義的 // 所以一旦解析器知道其中一個已經是表達式了,其它的也都默認為表達式了 var i = function () { return 10; } (); true && function () { /* code */ } (); 0, function () { /* code */ } (); // 如果你不在意返回值,或者不怕難以閱讀 // 你甚至可以在function前面加一元操作符號 !function () { /* code */ } (); ~function () { /* code */ } (); -function () { /* code */ } (); +function () { /* code */ } (); // 還有一個情況,使用new關鍵字,也可以用,但我不確定它的效率 // http://twitter.com/kuvos/status/18209252090847232 new function () { /* code */ } new function () { /* code */ } () // 如果需要傳遞參數,只需要加上括弧()
參考原文:
https://blog.csdn.net/figo333/article/details/80276302
https://www.cnblogs.com/beijingstruggle/p/5970824.html
https://blog.csdn.net/sinat_17775997/article/details/80263581