国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

進(jìn)擊的 JavaScript(五) 之 立即執(zhí)行函數(shù)與閉包

vincent_xyb / 1249人閱讀

摘要:匿名函數(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)算符

  圓括號(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


二、函數(shù)聲明

使用 function 關(guān)鍵字創(chuàng)建一個(gè)函數(shù),并且后面帶有函數(shù)名,叫函數(shù)聲明。

function testa(){}


三、匿名函數(shù)

那么使用 function 關(guān)鍵字創(chuàng)建的函數(shù)不帶函數(shù)名呢? 那就是匿名函數(shù)了。

function (){}


四、函數(shù)表達(dá)式

那么把匿名函數(shù)賦值給一個(gè)變量呢?那就是函數(shù)表達(dá)式了。

var testa = function (){}

其實(shí)呢,函數(shù)表達(dá)式的根本所在,就是阻止了js引擎把 function創(chuàng)建的函數(shù) 當(dāng)作函數(shù)聲明來解析。下面再詳說。


五、立即執(zhí)行函數(shù)(IIFE)

那么立即執(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ù)聲明解析。


六、立即執(zhí)行函數(shù)在閉包中的應(yīng)用

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

相關(guān)文章

  • 進(jìn)擊 JavaScript(四) 閉包

    摘要:此時(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...

    Anleb 評(píng)論0 收藏0
  • 進(jìn)擊JavaScript(三)玩轉(zhuǎn)閉包

    摘要:為了更好的理解,在閱讀此文之前建議先閱讀上一篇進(jìn)擊之詞法作用域與作用域鏈?zhǔn)裁词情]包閉包的含義就是閉合,包起來,簡(jiǎn)單的來說,就是一個(gè)具有封閉功能與包裹功能的結(jié)構(gòu)。在中函數(shù)構(gòu)成閉包。 為了更好的理解,在閱讀此文之前建議先閱讀上一篇《進(jìn)擊JavaScript之詞法作用域與作用域鏈》 1.什么是閉包 閉包的含義就是閉合,包起來,簡(jiǎn)單的來說,就是一個(gè)具有封閉功能與包裹功能的結(jié)構(gòu)。所謂的閉包就是...

    cyixlq 評(píng)論0 收藏0
  • 前端進(jìn)擊巨人():學(xué)會(huì)函數(shù)柯里化(curry)

    摘要:函數(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...

    chengtao1633 評(píng)論0 收藏0
  • 前端進(jìn)擊巨人(三):從作用域走進(jìn)閉包

    摘要:進(jìn)擊的巨人第三篇,本篇就作用域作用域鏈閉包等知識(shí)點(diǎn),一一擊破。在此我們遵照的方式,暫且稱是閉包。所以,一名合格的前端,除了會(huì)用閉包,還要正確的解除閉包引用。 進(jìn)擊的巨人第三篇,本篇就作用域、作用域鏈、閉包等知識(shí)點(diǎn),一一擊破。 showImg(https://segmentfault.com/img/bVburWd?w=1280&h=854); 作用域 作用域:負(fù)責(zé)收集并維護(hù)由所有聲明的...

    Vicky 評(píng)論0 收藏0
  • 進(jìn)擊JavaScript(一)變量聲明提升

    摘要:如下代碼輸出的結(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é)果是...

    LeexMuller 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<