摘要:在內(nèi)部,理所當(dāng)然能訪問(wèn)到局部變量,但當(dāng)作為的返回值賦給外的全局變量時(shí),神奇的事情發(fā)生了在全局作用域中訪問(wèn)到了,這就是閉包。而閉包最神奇的地方就是能在一個(gè)函數(shù)外訪問(wèn)函數(shù)中的局部變量,把這些變量用閉包的形式放在函數(shù)中便能避免污染。
一、閉包是什么?
二、閉包的原理?《JavaScript高級(jí)程序設(shè)計(jì)》中寫(xiě)道:“閉包是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)”,如果用下定義的觀點(diǎn)看,這句話就是說(shuō)“閉包是函數(shù)”,我?guī)е鴳岩傻男膽B(tài)又去網(wǎng)上找了找,發(fā)現(xiàn)什么說(shuō)法都有,終究沒(méi)能明白閉包的含義,還是看代碼來(lái)得直接。
function outter(){ var sky="blue"; function inner(){ console.log(sky); } return inner; } var result=outter(); result(); //"blue"這段代碼就包含一個(gè)簡(jiǎn)單的閉包:outter函數(shù)的返回值是一個(gè)函數(shù),即inner。inner在outter內(nèi)部,理所當(dāng)然能訪問(wèn)到局部變量sky,但當(dāng)inner作為outter的返回值賦給outter外的全局變量時(shí),神奇的事情發(fā)生了:在全局作用域中訪問(wèn)到了sky,這就是閉包。
三、閉包有什么用?每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境,當(dāng)一個(gè)函數(shù)被執(zhí)行時(shí),它的執(zhí)行環(huán)境就會(huì)被推入環(huán)境棧,其活動(dòng)對(duì)象(存儲(chǔ)環(huán)境中定義的變量及函數(shù))加入作用域鏈中,一旦函數(shù)執(zhí)行完,棧將其環(huán)境彈出,活動(dòng)對(duì)象被銷毀。
對(duì)于上面的例子來(lái)說(shuō),outter執(zhí)行完之后將返回inner給了result,outter的執(zhí)行環(huán)境從環(huán)境棧彈出,控制權(quán)交給全局環(huán)境,outter的活動(dòng)對(duì)象理應(yīng)被銷毀。但此時(shí)inner已經(jīng)存儲(chǔ)在全局活動(dòng)對(duì)象中了,同時(shí)inner需要訪問(wèn)sky,所以outter的活動(dòng)對(duì)象沒(méi)有被銷毀,即使result執(zhí)行完畢,outter的活動(dòng)對(duì)象依然存在于作用域鏈中,只有當(dāng)result被銷毀
result = null;outter的活動(dòng)對(duì)象才會(huì)徹底釋放。
四、Caveat說(shuō)了這么多,閉包到底有什么用呢?我個(gè)人認(rèn)為閉包最大的用處就是防止對(duì)全局作用域的污染。 試想如果我們把一些僅僅只用到一兩次的變量都聲明在全局作用域中,最后肯定是容易出錯(cuò)且不可維護(hù)的。而閉包最神奇的地方就是能在一個(gè)函數(shù)外訪問(wèn)函數(shù)中的局部變量,把這些變量用閉包的形式放在函數(shù)中便能避免污染。
閉包將函數(shù)的活動(dòng)對(duì)象維持在內(nèi)存中,過(guò)度使用閉包會(huì)導(dǎo)致內(nèi)存占用過(guò)多;
閉包只能取得外部函數(shù)中任何變量的最后一個(gè)值,在使用循環(huán)且返回的函數(shù)中帶有循環(huán)變量時(shí)會(huì)得到錯(cuò)誤結(jié)果;
當(dāng)返回的函數(shù)為匿名函數(shù)時(shí),注意匿名函數(shù)中的this指的是window對(duì)象。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83882.html
摘要:我們可以用普通函數(shù)內(nèi)部嵌套匿名函數(shù),形成一個(gè)閉包來(lái)使變量駐留在內(nèi)存中。局部變量閉包為什么要將賦值給變量呢這里我們就要談到匿名函數(shù)調(diào)用問(wèn)題匿名函數(shù)如何調(diào)用還是上面的例子會(huì)將整個(gè)函數(shù)體打印出來(lái)這樣才調(diào)用了函數(shù)內(nèi)部的匿名函數(shù)看到這里。 閉包含義: 閉包是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的常見(jiàn)的方式,就是在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù),通過(guò)另一個(gè)函數(shù)訪問(wèn)這個(gè)函數(shù)的局部變量。 這...
摘要:函數(shù)在執(zhí)行的時(shí)候執(zhí)行函數(shù),將當(dāng)前的變量對(duì)象由于當(dāng)前的環(huán)境是函數(shù),所以將其活動(dòng)對(duì)象作為變量對(duì)象添加到作用域鏈的前端。此時(shí),由于在執(zhí)行,而作用域鏈也存在,所以可以在作用域鏈上進(jìn)行查找,去訪問(wèn)的變量。 一、現(xiàn)狀 閉包是jser繞不過(guò)的坎,一直在都在說(shuō),套用 simpson 的話來(lái)說(shuō):JavaScript中閉包無(wú)處不在,你只需要能夠識(shí)別并擁抱它。 閉包是基于詞法作用域書(shū)寫(xiě)代碼時(shí)的自然結(jié)果,你甚...
摘要:但是函數(shù)返回了內(nèi)部函數(shù),內(nèi)部函數(shù)會(huì)隨時(shí)訪問(wèn)變量所以垃圾回收機(jī)制是不會(huì)回收函數(shù)的內(nèi)部作用域的,這就是閉包的含義。也就是函數(shù)在定義的詞法作用域以外的地方被調(diào)用,閉包使得函數(shù)可以繼續(xù)訪問(wèn)定義時(shí)的詞法作用域。 初學(xué)JavaScript閉包時(shí),閉包這個(gè)概念在我眼里及其的神秘,也不知道這個(gè)東西在講什么,尤其某些地方的閉包概念定義的非常抽象,屬于那種本來(lái)你可能明白這個(gè)概念,看了反而又把你給繞糊涂...
摘要:關(guān)于循環(huán)和閉包當(dāng)循環(huán)和閉包結(jié)合在一起時(shí),經(jīng)常會(huì)產(chǎn)生讓初學(xué)者覺(jué)得匪夷所思的問(wèn)題。閉包是一把雙刃劍是比較難以理解和掌握的部分,它十分強(qiáng)大,卻也有很大的缺陷,如何使用它完全取決于你自己。 在談閉包之前,我們首先要了解幾個(gè)概念: 什么是函數(shù)表達(dá)式? 與函數(shù)聲明有何不同? JavaScript查找標(biāo)識(shí)符的機(jī)制 JavaScript的作用域是詞法作用域 JavaScript的垃圾回收機(jī)制 先來(lái)...
摘要:將作用域賦值給變量這里的作用域是,而不是將作用域賦值給一個(gè)變量閉包返回瀏覽器中內(nèi)存泄漏問(wèn)題大家都知道,閉包會(huì)使變量駐留在內(nèi)存中,這也就導(dǎo)致了內(nèi)存泄漏。 上一章我們講了匿名函數(shù)和閉包,這次我們來(lái)談?wù)勯]包中作用域this的問(wèn)題。 大家都知道,this對(duì)象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局就是[object window],如果在對(duì)象內(nèi)部就是指向這個(gè)對(duì)象,而閉包卻是在運(yùn)行...
閱讀 2500·2021-11-17 09:33
閱讀 796·2021-11-04 16:13
閱讀 1358·2021-10-14 09:50
閱讀 718·2019-08-30 15:53
閱讀 3693·2019-08-30 14:18
閱讀 3287·2019-08-30 14:14
閱讀 2127·2019-08-30 12:46
閱讀 3207·2019-08-26 14:05