摘要:由于閉包函數(shù)是由調(diào)用的,所以一般它的指向。因?yàn)殚]包記住了它定義時(shí)候的作用域呀,這個(gè)時(shí)候的是塊級(jí)的,能夠好好地保存起來被閉包函數(shù)使用。
定義
當(dāng)函數(shù)可以記住并訪問它定義時(shí)候的作用域,就產(chǎn)生了閉包。也就是說,一個(gè)函數(shù)在另外一個(gè)函數(shù)里面定義,但是它執(zhí)行的時(shí)候,可能是在其他的作用域,但是它還是能夠憑著出生時(shí)的回憶,找到定義時(shí)的作用域,去訪問里面的變量。
function foo() { var a = 2; function bar() { console.log(a) } return bar; } var bar = foo(); bar();//記住了定義時(shí)的作用域,所以還是可以訪問到a,這里會(huì)輸出2
為什么能夠訪問到定義時(shí)候的作用域呢?答案只有一個(gè),定義閉包的函數(shù)是個(gè)重情義的家伙,考慮到那個(gè)寶寶可能隨時(shí)要用到它里面的變量,都不肯被回收。沒錯(cuò),這樣會(huì)導(dǎo)致foo的作用域一直沒有被回收,有一點(diǎn)浪費(fèi)內(nèi)存空間。
關(guān)于this對(duì)象一般函數(shù)的this指向的是調(diào)用它的對(duì)象。由于閉包函數(shù)是由window調(diào)用的,所以一般它的this指向window。如果你需要讓它指向某個(gè)對(duì)象,可以用call或者把外部的this保存起來,在里面直接使用。
var name = "window"; var object = { name: "My Object", //var that = this; getNameFunc: function() { return function() { console.log(this.name); //console.log(that.name); } } } object.getNameFunc()();//輸出"window" object.getNameFunc().call(object);//輸出"My Object"循環(huán)和閉包
很常見的一段代碼,運(yùn)行結(jié)果就是輸出5個(gè)5。因?yàn)檫@里的i沒有塊級(jí)作用域,也就是說閉包里面的函數(shù)訪問到外部的變量i只有一個(gè),加上setTimeout是異步的,執(zhí)行到里面的回調(diào)的時(shí)候,外面的這個(gè)i的值就是循環(huán)結(jié)束后的值5。
for(var i = 0; i < 5; i++) { setTimeout(function() { console.log(i); }, 1000) }
在沒有l(wèi)et的時(shí)候,我們都是通過模仿塊級(jí)作用域來解決。這個(gè)時(shí)候,閉包函數(shù)定義的作用域變成了(function(){}),然后在這個(gè)作用域里面把i的值賦值給j,每個(gè)閉包函數(shù)訪問到的j就是它定義時(shí)候作用域已經(jīng)保存好了的,自然就能夠正確的輸出。
for(var i = 0; i < 5; i++) { (function() { var j = i; setTimeout(function() {//閉包 console.log(j); }, 1000) })() }
當(dāng)然,我們一般都舍不得再用一個(gè)j來保存,直接用傳參數(shù)的形式,讓塊級(jí)作用域可以訪問到i的值。
for(var i = 0; i < 5; i++) { (function(j) { setTimeout(function() {//閉包 console.log(j); }, 1000) })(i) }
簡單改一下,每次用個(gè)塊級(jí)作用域的let來保存一下是不是就可以了啊
for(var i = 0; i < 5; i++) { let j = i; setTimeout(function() { console.log(j); }, 1000) }
哈哈哈,真的就輸出0 1 2 3 4 5了。因?yàn)殚]包記住了它定義時(shí)候的作用域呀,這個(gè)時(shí)候的j是塊級(jí)的,能夠好好地保存起來被閉包函數(shù)使用。
其實(shí)就是相當(dāng)于每次循環(huán)都會(huì)去聲明一個(gè)j,然后這個(gè)j的作用域就屬于這次循環(huán),所以可以直接把j的賦值寫在for循環(huán)里。
for(let j = 0; i < 5; i++) { setTimeout(function() { console.log(j); }, 1000) }模塊化
可以使用閉包來實(shí)現(xiàn)模塊化的。
var module = (function(window) { function test1() { } functon test2() { } return { test1: test1, test2: test2 } })(window)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/95393.html
摘要:閉包可以用來在一個(gè)函數(shù)與一組私有變量之間創(chuàng)建關(guān)聯(lián)關(guān)系。夾帶私貨外部變量返回的是函數(shù),帶私貨的函數(shù)支持將函數(shù)當(dāng)成對(duì)象使用的編程語言,一般都支持閉包。所以說當(dāng)你的裝飾器需要自定義參數(shù)時(shí),一般都會(huì)形成閉包。 Python中的閉包不是一個(gè)一說就能明白的概念,但是隨著你往學(xué)習(xí)的深入,無論如何你都需要去了解這么一個(gè)東西。 閉包的概念 我們嘗試從概念上去理解一下閉包。 在一些語言中,在函數(shù)中可以(嵌...
摘要:完美的閉包,對(duì),閉包就這么簡單。這僅僅是閉包的一部分,閉包利用函數(shù)作用域達(dá)到了訪問外層變量的目的。此時(shí)一個(gè)完整的閉包實(shí)現(xiàn)了,的垃圾回收機(jī)制由于閉包的存在無法銷毀變量。 1.閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)。 上面這段話來自 javascript 高級(jí)程序設(shè)計(jì) 第三版 P178 。作者說閉包是一個(gè)函數(shù),它有訪問另一個(gè)函數(shù)作用域中的變量的能力。 2.函數(shù)訪問它被創(chuàng)建時(shí)所處的...
摘要:在計(jì)算機(jī)科學(xué)中,閉包又稱詞法閉包或函數(shù)閉包,是引用了自由變量的函數(shù)。閉包被廣泛應(yīng)用于函數(shù)式語言中。運(yùn)用閉包可以避免對(duì)全局變量的使用。將棧頂?shù)脑厝〕觯瑒?chuàng)建元組,并將該元組進(jìn)棧。 在計(jì)算機(jī)科學(xué)中,閉包 又稱 詞法閉包 或 函數(shù)閉包,是引用了自由變量的函數(shù)。這個(gè)被引用的自由變量將和這個(gè)函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。閉包被廣泛應(yīng)用于函數(shù)式語言中。 從上面這段話中可以看出閉...
摘要:朋友,這就是閉包的效果。那么函數(shù)就是一個(gè)閉包,它可以在作用域外被訪問。封閉函數(shù)必須返回至少一個(gè)內(nèi)部函數(shù),這樣內(nèi)部函數(shù)才能在私有作用域中形成閉包,并且可以訪問或者修改私有的狀態(tài)。的模塊機(jī)制中為模塊增加了一級(jí)語法支持。 閉包 閉包是什么? 當(dāng)函數(shù)可以記住并訪問所在的詞法作用域時(shí),就產(chǎn)生了閉包,即使函數(shù)是在當(dāng)前詞法作用域之外執(zhí)行,簡單上講,就是在一個(gè)函數(shù)中內(nèi)部的函數(shù)。 function fo...
摘要:注理論上講閉包和匿名函數(shù)是不同的概念,不過將其視作相同的概念。匿名函數(shù)可以從父作用域繼承變量,而這個(gè)父作用域是定義該閉包的函數(shù)不一定是調(diào)用它的函數(shù)。 匿名函數(shù) 匿名函數(shù),也叫閉包函數(shù),說白了就是沒有名字的函數(shù),和一般函數(shù)結(jié)構(gòu)一樣,只是少了函數(shù)名以及最后需要加上分號(hào);。 注:理論上講閉包和匿名函數(shù)是不同的概念,不過PHP將其視作相同的概念。 $func = function() { ...
摘要:譯者按在上一篇博客,我們通過實(shí)現(xiàn)一個(gè)計(jì)數(shù)器,了解了如何使用閉包,這篇博客將提供一些代碼示例,幫助大家理解閉包。然而,如果通過代碼示例去理解閉包,則簡單很多。不過,將閉包簡單地看做局部變量,理解起來會(huì)更加簡單。 - 譯者按: 在上一篇博客,我們通過實(shí)現(xiàn)一個(gè)計(jì)數(shù)器,了解了如何使用閉包(Closure),這篇博客將提供一些代碼示例,幫助大家理解閉包。 原文: JavaScript Clos...
閱讀 1582·2021-09-02 15:41
閱讀 993·2021-09-02 15:11
閱讀 1274·2021-07-28 00:15
閱讀 2296·2019-08-30 15:55
閱讀 1137·2019-08-30 15:54
閱讀 1686·2019-08-30 15:54
閱讀 2967·2019-08-30 14:02
閱讀 2518·2019-08-29 16:57