摘要:匿名函數(shù)是不能多帶帶寫的,所以就提不上立即執(zhí)行了。六立即執(zhí)行函數(shù)在閉包中的應(yīng)用立即執(zhí)行函數(shù)能配合閉包保存狀態(tài)。來看下上節(jié)內(nèi)容中閉包的例子現(xiàn)在,我們來利用立即執(zhí)行函數(shù)來簡(jiǎn)化它第一個(gè)匿名函數(shù)執(zhí)行完畢后,返回了第二個(gè)匿名函數(shù)。
前面的閉包中,提到與閉包相似的立即執(zhí)行函數(shù),感覺兩者還是比較容易弄混吧,嚴(yán)格來說(因?yàn)橄透叱虒?duì)閉包的定義不同),立即執(zhí)行函數(shù)并不屬于閉包,它不滿足閉包的三個(gè)條件。
圓括號(hào)運(yùn)算符也叫分組運(yùn)算符,它有兩種用法:如果表達(dá)式放在圓括號(hào)中,作用是求值;如果跟在函數(shù)后面,作用是調(diào)用函數(shù)
把表達(dá)式放在圓括號(hào)之中,將返回表達(dá)式的值
console.log((1+2)); // 3
將函數(shù)放在圓括號(hào)中,會(huì)返回函數(shù)本身。如果圓括號(hào)緊跟在函數(shù)的后面,就表示調(diào)用函數(shù),即對(duì)函數(shù)求值
console.log((function testa(){return 666;})); // function testa(){return 666;} console.log(function testa(){return 666;}()); // 666
注意:圓括號(hào)運(yùn)算符不能為空,否則會(huì)報(bào)錯(cuò)
();//SyntaxError: Unexpected token )
由于圓括號(hào)的作用是求值,如果將語句放在圓括號(hào)之中,就會(huì)報(bào)錯(cuò),因?yàn)檎Z句沒有返回值
(var a = function(){return 666}); // SyntaxError: Unexpected token var
使用 function 關(guān)鍵字創(chuàng)建一個(gè)函數(shù),并且后面帶有函數(shù)名,叫函數(shù)聲明。
function testa(){}
那么使用 function 關(guān)鍵字創(chuàng)建的函數(shù)不帶函數(shù)名呢? 那就是匿名函數(shù)了。
function (){}
那么把匿名函數(shù)賦值給一個(gè)變量呢?那就是函數(shù)表達(dá)式了。
var testa = function (){}
其實(shí)呢,函數(shù)表達(dá)式的根本所在,就是阻止了js引擎把 用function創(chuàng)建的函數(shù) 當(dāng)作函數(shù)聲明來解析。下面再詳說。
那么立即執(zhí)行函數(shù)呢?
用function定義函數(shù)之后,立即調(diào)用該函數(shù)。這種函數(shù)就叫做立即執(zhí)行函數(shù),全稱為立即調(diào)用的函數(shù)表達(dá)式IIFE(Imdiately Invoked Function Expression)
1、在本系列進(jìn)擊的 JavaScript(三)中到過,代碼執(zhí)行時(shí),會(huì)先對(duì)函數(shù)聲明的函數(shù) 進(jìn)行解析(函數(shù)聲明提升),而函數(shù)表達(dá)式,當(dāng)逐行執(zhí)行到它時(shí),才會(huì)解析。
2、正因?yàn)楹瘮?shù)聲明的提升,導(dǎo)致函數(shù)聲明不能立即執(zhí)行。因?yàn)?,函?shù)聲明時(shí),js只會(huì)解析到大括號(hào)(})就結(jié)束了,如果后面有(),只是一個(gè)圓括號(hào)運(yùn)算符。
function testa(){ console.log("testa") }("666") //"666" //如果后面是一個(gè)空的圓括號(hào),會(huì)報(bào)錯(cuò),上面提到過。
所以,不知道,你有沒有發(fā)現(xiàn),函數(shù)聲明的函數(shù),后面可以不用分號(hào)(;)分隔,也可以正常執(zhí)行,而函數(shù)表達(dá)式的后面就必須加分號(hào),不然會(huì)報(bào)錯(cuò)。你可以自己寫個(gè)小栗子驗(yàn)證下。
3、匿名函數(shù)是不能多帶帶寫的,所以就提不上立即執(zhí)行了。
function (){} //Uncaught SyntaxError: Unexpected token (
多帶帶寫匿名函數(shù),是會(huì)報(bào)錯(cuò)的,js引擎 會(huì)把它當(dāng)作函數(shù)聲明來解析,而函數(shù)聲明就必須要有個(gè)函數(shù)名,所以會(huì)報(bào)錯(cuò)。
所以,你通??吹绞褂媚涿瘮?shù),都是當(dāng)作參數(shù)傳遞的,或者把匿名函數(shù)轉(zhuǎn)為函數(shù)表達(dá)式。
4、因此,只有函數(shù)表達(dá)式可以立即執(zhí)行
var testa = function (){ console.log("testa") }() //"testa"
上面提到過,函數(shù)表達(dá)式,就是阻止了js引擎把 |用function創(chuàng)建的函數(shù)| 當(dāng)作函數(shù)聲明來解析。
注:javascript引擎規(guī)定,如果function關(guān)鍵字出現(xiàn)在行首,一律解釋成函數(shù)聲明語句。
所以,解決方法就是不要讓function出現(xiàn)在行首,讓引擎將其理解成一個(gè)表達(dá)式。
//常用的兩種,使用圓括號(hào)運(yùn)算符 (function(){console.log("666")})() (function(){console.log("666")}()) //一元運(yùn)算符寫法 !function(){console.log("666")}() +function(){console.log("666")}() -function(){console.log("666")}() ~function(){console.log("666")}()
都是都可以把函數(shù)聲明 轉(zhuǎn)為 函數(shù)表達(dá)式,也就是阻止了把其當(dāng)作函數(shù)聲明解析。
1、立即執(zhí)行函數(shù)能配合閉包保存狀態(tài)。
來看下 上節(jié)內(nèi)容中閉包的例子:
function makeClosures(i){ var i = i; return function(){ console.log(i); } } for (var i=1; i<=5; i++) { setTimeout(makeClosures(i),i*1000); } //1 //2 //3 //4 //5
現(xiàn)在,我們來利用立即執(zhí)行函數(shù)來簡(jiǎn)化它:
for (var i=1; i<=5; i++) { setTimeout((function(i){ return function(){ console.log(i); } })(i),i*1000); }
第一個(gè)匿名函數(shù)執(zhí)行完畢后,返回了第二個(gè)匿名函數(shù)。第二個(gè)匿名函數(shù)被當(dāng)做setTimeout 的第一個(gè)參數(shù)傳入進(jìn)去。因?yàn)?setTimeout函數(shù)執(zhí)行了5次,所以立即執(zhí)行函數(shù)里每次都會(huì)返回了一個(gè)沒有被執(zhí)行的匿名函數(shù),(這里就是返回了5個(gè)匿名函數(shù)),每個(gè)匿名函數(shù)內(nèi)部保存著每次傳進(jìn)來的i值,因此,每個(gè)i 都是不一樣的,所以,就得到了想要的結(jié)果
2、立即執(zhí)行函數(shù)配合閉包 模塊化中應(yīng)用
(function(){ var meg = "hello zdx"; function say(arg){ arg = arg || meg; console.log(arg) } window.say = say; })(window) window.say(); //"hello zdx"
首先立即執(zhí)行函數(shù),它是個(gè)匿名函數(shù),你是得不到它的函數(shù)引用,這樣,就避免了全局變量污染。其次,由于函數(shù)作用域的規(guī)則,在匿名函數(shù)外部是訪問不了函數(shù)內(nèi)的變量,函數(shù)等的。所以,也經(jīng)常用立即執(zhí)行函數(shù)模擬塊級(jí)作用域。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/96145.html
摘要:此時(shí)產(chǎn)生了閉包。導(dǎo)致,函數(shù)的活動(dòng)對(duì)象沒有被銷毀。是不是跟你想的不一樣其實(shí),這個(gè)例子重點(diǎn)就在函數(shù)上,這個(gè)函數(shù)的第一個(gè)參數(shù)接受一個(gè)函數(shù)作為回調(diào)函數(shù),這個(gè)回調(diào)函數(shù)并不會(huì)立即執(zhí)行,它會(huì)在當(dāng)前代碼執(zhí)行完,并在給定的時(shí)間后執(zhí)行。 上一節(jié)說了執(zhí)行上下文,這節(jié)咱們就乘勝追擊來搞搞閉包!頭疼的東西讓你不再頭疼! 一、函數(shù)也是引用類型的。 function f(){ console.log(not cha...
摘要:為了更好的理解,在閱讀此文之前建議先閱讀上一篇進(jìn)擊之詞法作用域與作用域鏈?zhǔn)裁词情]包閉包的含義就是閉合,包起來,簡(jiǎn)單的來說,就是一個(gè)具有封閉功能與包裹功能的結(jié)構(gòu)。在中函數(shù)構(gòu)成閉包。 為了更好的理解,在閱讀此文之前建議先閱讀上一篇《進(jìn)擊JavaScript之詞法作用域與作用域鏈》 1.什么是閉包 閉包的含義就是閉合,包起來,簡(jiǎn)單的來說,就是一個(gè)具有封閉功能與包裹功能的結(jié)構(gòu)。所謂的閉包就是...
摘要:函數(shù)柯里化是把支持多個(gè)參數(shù)的函數(shù)變成接收單一參數(shù)的函數(shù),并返回一個(gè)函數(shù)能接收處理剩余參數(shù),而反柯里化就是把參數(shù)全部釋放出來。但在一些復(fù)雜的業(yè)務(wù)邏輯封裝中,函數(shù)柯里化能夠?yàn)槲覀兲峁└玫膽?yīng)對(duì)方案,讓我們的函數(shù)更具自由度和靈活性。 showImg(https://segmentfault.com/img/bVburN1?w=800&h=600); 柯里化(Curring, 以邏輯學(xué)家Has...
摘要:進(jìn)擊的巨人第三篇,本篇就作用域作用域鏈閉包等知識(shí)點(diǎn),一一擊破。在此我們遵照的方式,暫且稱是閉包。所以,一名合格的前端,除了會(huì)用閉包,還要正確的解除閉包引用。 進(jìn)擊的巨人第三篇,本篇就作用域、作用域鏈、閉包等知識(shí)點(diǎn),一一擊破。 showImg(https://segmentfault.com/img/bVburWd?w=1280&h=854); 作用域 作用域:負(fù)責(zé)收集并維護(hù)由所有聲明的...
摘要:如下代碼輸出的結(jié)果是代碼執(zhí)行分為兩個(gè)大步預(yù)解析的過程代碼的執(zhí)行過程預(yù)解析與變量聲明提升程序在執(zhí)行過程中,會(huì)先將代碼讀取到內(nèi)存中檢查,會(huì)將所有的聲明在此進(jìn)行標(biāo)記,所謂的標(biāo)記就是讓解析器知道有這個(gè)名字,后面在使用名字的時(shí)候不會(huì)出現(xiàn)未定義的錯(cuò)誤。 showImg(https://segmentfault.com/img/remote/1460000012922850); 如下代碼輸出的結(jié)果是...
閱讀 1503·2021-11-22 09:34
閱讀 3320·2021-09-29 09:35
閱讀 562·2021-09-04 16:40
閱讀 2912·2019-08-30 15:53
閱讀 2582·2019-08-30 15:44
閱讀 2584·2019-08-30 14:10
閱讀 1328·2019-08-29 18:43
閱讀 2205·2019-08-29 13:26