摘要:第一種方法是上面已經(jīng)說到的匿名函數(shù)表達式,即將匿名函數(shù)賦值給一個變量,然后通過變量名去調用。因為函數(shù)聲明是不能被執(zhí)行符號執(zhí)行的,除非通過函數(shù)名調用,只有表達式才能被執(zhí)行符號執(zhí)行匿名函數(shù)又沒有函數(shù)名,另外的辦法就是把它變成表達式。
函數(shù)聲明
function funcName(){ }; console.log(funcName); // 打印結果是funcName這個函數(shù)體。
聲明一個函數(shù)funcName,funcName就是函數(shù)名,函數(shù)名是函數(shù)聲明的必要組成部分,函數(shù)其實就是另一個類型的變量,函數(shù)名稱相當于變量名,新聲明的函數(shù)體會賦值給這個變量名,之后調用該函數(shù)的時候都需要通過該變量名進行調用。
函數(shù)表達式
// 命名函數(shù)表達式 var funcName = function abc() {}; console.log(funcName); // 打印函數(shù)體function abc(){} console.log(abc); // 報錯(abc is not defined)
在這個函數(shù)表達式中,函數(shù)名稱為abc,其實上,這個名稱abc變成了函數(shù)內部的一個局部變量,并且指代函數(shù)對象本身,在abc函數(shù)內部打印abc的打印結果是abc函數(shù)體本身。
var funcName = function abc() { console.log(abc); // 打印結果是function abc() {console.log(abc)} };
所以,在全局console.log(abc);肯定會報錯,因為abc是局部變量,全局是拿不到的,這個函數(shù)表達式會忽略函數(shù)的名稱,調用的時候要通過變量名進行調用——funcName();
// 匿名函數(shù)表達式 var funcName = function () {};
匿名函數(shù)表達式顧名思義就是沒有名字的函數(shù)表達式,一般情況下,我們所說函數(shù)表達式就指匿名函數(shù)表達式,因為函數(shù)表達式會忽略函數(shù)的名稱,會變成匿名函數(shù)表達式,不如直接寫成匿名函數(shù)表達式。
函數(shù)表達式與函數(shù)聲明不同的是,函數(shù)聲明只是聲明了一個函數(shù),在預編譯的時候,函數(shù)聲明的聲明提升函數(shù)體也提升,所以不管你是在函數(shù)聲明之前調用還是在之后調用,都能正常執(zhí)行。
demo(); // 結果是"a" function demo(){ console.log("a"); }; demo(); // 結果是"a"
而函數(shù)表達式在預編譯時,是變量名提升,只有當執(zhí)行到函數(shù)表達式所在行的代碼時,才將函數(shù)體賦值給該變量,所以在函數(shù)表達式之前調用該函數(shù)會報錯,只能在之后調用。
demo(); // 報錯 var demo = function (){ console.log("a") }; demo(); // 結果是"a"
匿名函數(shù)
匿名函數(shù)顧名思義就是沒有名字的函數(shù)。(匿名函數(shù)有多種用途,寫在文末)
function () {};
既然是沒有名字的函數(shù),那我們要怎樣找到它調用它呢?這里要提到兩種方法。
第一種方法是上面已經(jīng)說到的匿名函數(shù)表達式,即將匿名函數(shù)賦值給一個變量,然后通過變量名去調用。
var abc = function (){}; abc();
第二種方法就是接下來要說的立即執(zhí)行函數(shù)。
立即執(zhí)行函數(shù)
立即執(zhí)行函數(shù)有兩種寫法:
// 第一種 w3c標準建議使用這一種 (function (){})(); // 第二種 (function(){}());
這里有兩個括號有點疑問,在解釋兩個括號的作用前,我們先明確幾點:
1.只有表達式才能被執(zhí)行符號執(zhí)行,函數(shù)聲明是不能被執(zhí)行符號執(zhí)行的。
2.能被執(zhí)行符號執(zhí)行的表達式,這個函數(shù)的名字就會被自動忽略(放棄名字)。
3.能被執(zhí)行符號執(zhí)行的表達式基本上就是立即執(zhí)行函數(shù)。
因為函數(shù)聲明是不能被執(zhí)行符號執(zhí)行的,除非通過函數(shù)名調用,只有表達式才能被執(zhí)行符號執(zhí)行(匿名函數(shù)又沒有函數(shù)名,另外的辦法就是把它變成表達式)。
function (){ console.log("a"); // 報語法錯誤,因為只有表達式才能被執(zhí)行符號()執(zhí)行 }();
(function (){})()
所以此處匿名函數(shù)兩邊的括號運算符,作用是把函數(shù)轉換為表達式(至于怎樣轉換的,更深層的原理有興趣的童鞋可以研究研究,后續(xù)我會進行補充的),后面的括號為執(zhí)行符號,(function (){})()就相當于匿名函數(shù)表達式的執(zhí)行。
(function (){})()和(function(){}())寫法其實沒多大區(qū)別,(function(){}())也是一直等價的表達式,但是w3c標準建議使用第一種。
將函數(shù)聲明轉化成表達式的方式有很多,例如把它賦值給一個變量,再例如在函數(shù)聲明前放上+運算符,-運算符,!運算符等。
// 把它賦值給一個變量 var demo = function(a){ console.log(a); // 結果為1 }(1) // 使用+運算符 +function(a){ console.log(a); // 結果為1 }(1); // 使用-運算符 -function(a){ console.log(a); // 結果為1 }(1); // 使用!運算符 !function(a){ console.log(a); // 結果為1 }(1);
當表達式被執(zhí)行,函數(shù)的名字就會被放棄,舉兩個栗子:
var demo = function(){}(); console.log(demo); // 結果會報錯,因為函數(shù)名被放棄了。 +function demo(){}(); console.log(demo); // 結果會報錯,因為函數(shù)名被放棄了。
匿名函數(shù)有很多作用,例如將匿名函數(shù)賦予一個變量來創(chuàng)建一個函數(shù),例如賦予一個事件則成為事件處理程序,再例如用立即執(zhí)行函數(shù)創(chuàng)建閉包防止污染全局變量等等
// 將匿名函數(shù)賦予一個變量來創(chuàng)建一個函數(shù) var demo = function(){}; // 賦予一個事件則成為事件處理程序 $(selector).on("click",function(){}); // 用立即執(zhí)行函數(shù)創(chuàng)建閉包 (function(window, undefined))(window);
本文只是簡單分析以助自己理清思路,有錯誤之處請不吝賜教。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/109072.html
摘要:而且,如果你想跳過這里,你可以直接跳到立即調用函數(shù)表達式進行閱讀,但是我建議你讀完整篇文章。當圓括號包裹函數(shù)時,它會默認將函數(shù)作為表達式去解析,而不是函數(shù)聲明。什么是呢它使一個被立即調用的函數(shù)表達式。一旦命名,函數(shù)將不再匿名。 原文:http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iif...
摘要:另外,如果你想跳過這里,你可以直接跳到立即調用函數(shù)表達式進行閱讀,但是我建議你讀完整篇文章。當圓括號包裹函數(shù)時,它會默認將函數(shù)作為表達式去解析,而不是函數(shù)聲明。 原文:Immediately-Invoked Function Expression (IIFE) by Ben Alman原譯:立即執(zhí)行函數(shù) by Murphywuwu改增內容: by blanu 也許你沒有注意到,我是一個...
摘要:前言最近在學前幾天看到兩道題剛開始看懵懵懂懂這幾天通過各種查資料慢慢的理解頓悟了對匿名函數(shù)閉包立即執(zhí)行函數(shù)的理解也更深了一點在此分享給大家我的理解與總結希望能幫助大家理解因為這篇文章是我用心總結的查閱了很多的資料所以總結的比較細篇幅較長如果 前言 最近在學JS,前幾天看到兩道題,剛開始看懵懵懂懂,這幾天通過各種查資料,慢慢的理解,頓悟了,對匿名函數(shù),閉包,立即執(zhí)行函數(shù)的理解也更深了一點...
摘要:而閉包的神奇之處正是可以阻止事情的發(fā)生。拜所聲明的位置所賜,它擁有涵蓋內部作用域的閉包,使得該作用域能夠一直存活,以供在之后任何時間進行引用。依然持有對該作用域的引用,而這個引用就叫閉包。 引子 先看一個問題,下面兩個代碼片段會輸出什么? // Snippet 1 a = 2; var a; console.log(a); // Snippet 2 console.log(a); v...
摘要:匿名函數(shù)的好處在于可以減少局部變量,以免污染現(xiàn)有的運行環(huán)境。另外通過,這三個符號運行的匿名函數(shù)比運行的匿名函數(shù)可以減少一個字符的使用但是我們通常使用加因為其他的操作符可能會帶來其他的影響更多可以參考 js中的立即執(zhí)行函數(shù) ( function(){…} )()和( function (){…} () )是兩種javascript立即執(zhí)行函數(shù)的常見寫法 問題: 為什么會出現(xiàn)上面的兩種不一...
閱讀 1570·2023-04-26 02:29
閱讀 3060·2021-10-11 10:58
閱讀 2904·2021-10-08 10:16
閱讀 3163·2021-09-24 09:47
閱讀 1571·2019-08-29 16:56
閱讀 2723·2019-08-29 11:03
閱讀 2009·2019-08-26 13:35
閱讀 3175·2019-08-26 13:34