内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

javascript的函數(shù)和閉包-創(chuàng)新互聯(lián)

每聲明一個函數(shù)就會產(chǎn)生一個作用域。而外面的作用域訪問不了里面的作用域(把里面的變量和函數(shù)起來),而里面的可以訪問到外面的。對于隱藏變量和函數(shù)是一個非常有用的技術(shù)。

北屯ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!

javascript的函數(shù)和閉包

基于作用域隱藏的方法叫做或。

這個原則是指在軟件設(shè)計中,應(yīng)該最小限度的暴露必要內(nèi)容,而將其內(nèi)容都隱藏起來,比如某個模塊或?qū)ο蟮肁PI設(shè)計。,沖突會導(dǎo)致變量的意外覆蓋。

例如:

var a = 2;
function foo(){
  var a = 3;
  console.log(a);
}
foo();
console.log(a);

雖然這種技術(shù)可以解決一些問題,但是他并不理想,會導(dǎo)致一些額外的問題,首先必須聲明一個具名函數(shù)foo(),意味著foo這個名稱本身“污染”了所在的作用域,其次必須顯式的通過函數(shù)名foo()調(diào)用這個函數(shù)才能運行其中的代碼。


如果函數(shù)不需要函數(shù)名,并且能夠自動運行,這會更加理想。幸好js提供了同時解決這兩個問題的方案 -- (IIFE) Immediately Invoked Function Expression  --  

var a = 2;
(function foo(){
    var a = 3;
    console.log(a);
})()
console.log(a);

首先不會當(dāng)做函數(shù)聲明處理而當(dāng)做處理。


看function在聲明中是不是第一個詞,如果是第一個詞就是函數(shù)聲明否則就是函數(shù)表達式。而立即執(zhí)行函數(shù)" (function ",不是"   function ",所以是函數(shù)表達式。

函數(shù)聲明和最的區(qū)別

函數(shù)聲明的函名稱數(shù)會綁定在當(dāng)前作用域內(nèi)。假如在全局作用域創(chuàng)建一個函數(shù)聲明,就可以在全局作用域訪問這個函數(shù)名稱并執(zhí)行。而函數(shù)表達式的函數(shù)名稱會綁定在自身的函數(shù)中,而不是當(dāng)前說在作用域中。例如你全局創(chuàng)建一個函數(shù)表達式,如果你直接執(zhí)行這個你創(chuàng)建的函數(shù)表達式的函數(shù)名就會報錯,因為當(dāng)前作用域下沒有這個標識符,而你在函數(shù)表達式里面的作用域里訪問這個函數(shù)名就會返回這個函數(shù)的引用。

作用域閉包,嗯,閉包這兒兩個字就有點讓人難以理解,(可以想象成一個包是關(guān)上的,里面隱藏了一些神秘的東西)而對于閉包的定義是這樣說的:當(dāng)函數(shù)可以記住并訪問所在的作用域時,就產(chǎn)生了閉包,即使函數(shù)是在當(dāng)前作用域之外執(zhí)行。

for instance

function foo() {
    var a = 2;
    function bar() {
        console.log(a);
    }
    bar();
}
foo();

上面的 代碼bar()可以訪問外部作用域中的變量。根據(jù)上面的定義這是閉包嗎?從技術(shù)來講也許是,但我們理解的是作用域在當(dāng)前作用域查找變量如果沒找到會繼續(xù)向上面查找,找到返回,找不到繼續(xù)找,直到全局作用域。-- 而這些正是閉包的一部分。函數(shù)bar()具有一個涵蓋foo()作用域的閉包。

function foo(){    var a  = 2;    function bar (){
        console.log(a);
    }    return bar;
}var baz = foo();
baz();

在上面的代碼更好的展示了閉包。

bar()函數(shù)在定義時作用域以外的地方執(zhí)行(此時在全局作用域執(zhí)行)。在foo()函數(shù)執(zhí)行后,通常會期待foo()整個內(nèi)部作用域都被銷毀,因為我們知道引擎有用來釋放不在使用的內(nèi)存空間,由于foo()已經(jīng)執(zhí)行完,看上去內(nèi)容不會再被使用,所以很自然的會考慮對齊進行回收,回收后意味著里面的函數(shù)和變量訪問不到了。foo()執(zhí)行完,baz變量存著bar函數(shù)的引用。當(dāng)執(zhí)行baz也就是bar函數(shù)時。console.log(a)。不理解閉包的人可能認為會報錯,事實上,打印的是2;???what?

foo()函數(shù)作用域不是執(zhí)行完銷毀了嗎?怎么還能訪問到a變量?-- 這就是閉包。

當(dāng)foo()執(zhí)行后,bar函數(shù)被返回全局作用域下,但是bar函數(shù)還保留著當(dāng)時的詞法作用域(當(dāng)時寫代碼是的順序就已經(jīng)定義了作用域,這個作用域叫詞法作用域--外面函數(shù)套著里面的函數(shù)的那種)甚至直到全局作用域。所以bar還留有foo()函數(shù)的引用。使得foo()函數(shù)沒有被回收。

閉包可以說不出不在,只是你沒有發(fā)現(xiàn)認出他。在定時器,事件監(jiān)聽器,ajax請求,跨窗口通信或者任何其他的異步(或者同步)任務(wù)中,只要使用了回調(diào)函數(shù),實際上就是使用閉包。

for instance

function wait(message) {
    setTimeout(function timer() {
        console.log(message);
    }, 1000);
}
wait("hello");

在上面的代碼中將一個內(nèi)部函數(shù)(名為timer)傳遞給setTimerout(...).timer具有涵蓋wait(...)的作用域的閉包。因此還保有對變量message的引用。wait()執(zhí)行1000毫秒后,它的內(nèi)部作用域不會消失,timer函數(shù)依然保有wait()作用域的閉包。

而閉包和立即執(zhí)行函數(shù)息息相關(guān)。

循環(huán)和閉包

for(var i = 1; i <= 5; i++){
    setTimeout(function timer(){
        console.log(i);
    },i*1000);
}

上面代碼我們以為輸出的會是1-5,可事實上輸出的是5個6,這是為啥啊 -- 閉包啊。

延遲函數(shù)的回調(diào)會在循環(huán)結(jié)束時執(zhí)行。事實上,當(dāng)定時器運行時即使每個迭代的是setTimerout(...,0),所有的回調(diào)函數(shù)依然是循環(huán)結(jié)束后才會執(zhí)行。我猜是跟js執(zhí)行機制有關(guān)系吧。至于為什么都是6. 因為即使5個函數(shù)是在各個迭代中分別定義的,但是他們又被封閉在一個共享的全局作用域中因此實際上只有一個i.而怎么解決呢,立即執(zhí)行函數(shù)來了?。?!

for (var i = 1; i <= 5; i++) {
    (function (i) {
        setTimeout(function timer() {
            console.log(i);
        }, i * 1000);
    })(i)

}

打印出來1,2,3,4,5了歐,這回是你想要的數(shù)了。解釋一下,5次循環(huán)創(chuàng)建了5個立即執(zhí)行函數(shù),這5個函數(shù)的作用域都不相同,立即函數(shù)接收的參數(shù)是當(dāng)前循環(huán)的i.所以當(dāng)timer執(zhí)行時訪問的就是自己立即執(zhí)行函數(shù)對應(yīng)的作用域。也就是說5個timer函數(shù)分別對應(yīng)5個作用域,每個作用域保存的變量i都不同,解決啦?。?!

你懂閉包了嗎?

js執(zhí)行機制

JavaScript語言的一大特點就是單線程,也就是說,同一個時間只能做一件事。那么,為什么JavaScript不能有多個線程呢?這樣能提高效率啊。JavaScript的單線程,與它的用途有關(guān)。作為瀏覽器腳本語言,JavaScript的主要用途是與用戶互動,以及操作DOM。這決定了它只能是單線程,否則會帶來很復(fù)雜的同步問題。比如,假定JavaScript同時有兩個線程,一個線程在某個DOM節(jié)點上添加內(nèi)容,另一個線程刪除了這個節(jié)點,這時瀏覽器應(yīng)該以哪個線程為準所以,為了避免復(fù)雜性,從一誕生,JavaScript就是單線程,這已經(jīng)成了這門語言的核心特征,將來也不會改變。

單線程就意味著,所有任務(wù)需要排隊,前一個任務(wù)結(jié)束,才會執(zhí)行后一個任務(wù)。如果前一個任務(wù)耗時很長,后一個任務(wù)就不得不一直等著。JavaScript語言的設(shè)計者意識到這個問題,將所有任務(wù)分成兩種,一種是同步任務(wù)(synchronous),另一種是異步任務(wù)(asynchronous)。同步任務(wù)指的是,在主線程上排隊執(zhí)行的任務(wù),只有前一個任務(wù)執(zhí)行完畢,才能執(zhí)行后一個任務(wù);異步任務(wù)指的是,不進入主線程、而進入"任務(wù)隊列"(task queue)的任務(wù),只有"任務(wù)隊列"通知主線程,某個異步任務(wù)可以執(zhí)行了,該任務(wù)才會進入主線程執(zhí)行。

主線程從"任務(wù)隊列"中讀取事件,這個過程是循環(huán)不斷的,所以整個的這種運行機制又稱為Event Loop(事件循環(huán))。只要主線程空了,就會去讀取"任務(wù)隊列",這就是JavaScript的運行機制。

哪些語句會放入異步任務(wù)隊列及放入時機一般來說,有以下四種會放入異步任務(wù)隊列:setTimeout 和 setlnterval  ,DOM事件,ES6中的Promise,Ajax異步請求

以上就是淺談JS函數(shù)及閉包的詳細內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)其它相關(guān)文章!


另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

名稱欄目:javascript的函數(shù)和閉包-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://m.rwnh.cn/article2/ddooic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機、外貿(mào)網(wǎng)站建設(shè)、微信公眾號、移動網(wǎng)站建設(shè)、軟件開發(fā)、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名
岳西县| 密山市| 迁安市| 枞阳县| 申扎县| 海淀区| 鄂伦春自治旗| 汾西县| 德保县| 呈贡县| 图木舒克市| 阳原县| 孝义市| 虎林市| 沾化县| 陆川县| 定兴县| 台北县| 河西区| 铁力市| 浦北县| 阿坝| 闽侯县| 西畴县| 黑河市| 九龙城区| 红原县| 洛隆县| 乃东县| 武强县| 济阳县| 东至县| 泌阳县| 大姚县| 中山市| 安达市| 安西县| 丹棱县| 察隅县| 澳门| 广东省|