摘要:我們可以用普通函數(shù)內(nèi)部嵌套匿名函數(shù),形成一個(gè)閉包來使變量駐留在內(nèi)存中。局部變量閉包為什么要將賦值給變量呢這里我們就要談到匿名函數(shù)調(diào)用問題匿名函數(shù)如何調(diào)用還是上面的例子會(huì)將整個(gè)函數(shù)體打印出來這樣才調(diào)用了函數(shù)內(nèi)部的匿名函數(shù)看到這里。
閉包含義:
閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的常見的方式,就是在
一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù),通過另一個(gè)函數(shù)訪問這個(gè)函數(shù)的局部變量。
這個(gè)時(shí)候我們就要談到匿名函數(shù)了.
匿名函數(shù)
匿名函數(shù)就是沒有名字的函數(shù),閉包是可訪問一個(gè)函數(shù)作用域里變量的函數(shù)??蠢樱?/p>
function box () { //這是一個(gè)普通函數(shù) return "anonymous"; } alert(box());
那么匿名函數(shù)是什么呢?看例子:
function () { return "anonymous"; }
這個(gè)函數(shù)并沒有執(zhí)行?。。?br>如果讓匿名函數(shù)執(zhí)行呢。我們可以將匿名函數(shù)賦值給一個(gè)變量:
var box = function (){ return "anonymous"; }; alert(box()); //anonymous
但是這種表達(dá)式有時(shí)候并沒有什么含義,那我們可以用自執(zhí)行的方法去調(diào)用匿名函數(shù):
(function () { alert("anonymous"); })();
匿名函數(shù)如何傳參呢?看例子:
(function (a) { alert(a); })(100); //alert返回100匿名函數(shù)和閉包的作用
談到閉包,我們就不得不談到全局變量和局部變量。
全局變量:
全局變量在實(shí)際寫項(xiàng)目中個(gè)人額不建議使用,因?yàn)榇罅康娜肿兞繒?huì)污染代碼,每個(gè)模塊都可以去地道用,必將引來很多錯(cuò)誤。所以推薦變量私有化。
什么是變量私有化?
var a = 100; //全局變量 function box () { alert(a); } box(); //調(diào)用函數(shù)返回100
通過上面的代碼可以看出,每個(gè)函數(shù)內(nèi)都可以調(diào)用外部的局部變量。將a變量變成了公有化的變量,有時(shí)候我們并不希望這么做。所以我們可以將變量定義在函數(shù)內(nèi)部使變量變成私有化變量,外部無法訪問到這個(gè)變量
function box () { var a = 100; //局部變量 } alert(a); //a is not defined
這就完事了么?并沒有?。∮涀∫稽c(diǎn):局部變量在每次調(diào)用時(shí)都會(huì)初始化?。。。ㄖ匾氖虑橛萌齻€(gè)感嘆號(hào)...)
我們來用一個(gè)后置遞增的一個(gè)小例子來告訴大家:
function a () { var b = 100; b++; return b; } alert(a()); //101 alert(a()); //101
不難看出,每次調(diào)用,變量b都會(huì)被初始化,所以每次調(diào)用都會(huì)返回101而不是累加。我們可以用普通函數(shù)內(nèi)部嵌套匿名函數(shù),形成一個(gè)閉包來使變量駐留在內(nèi)存中。
function a () { var b = 100; //局部變量 return function () { //閉包 b++; return b; }; } var c = a(); alert(c()); //101 alert(c()); //102
為什么要將a()賦值給變量c呢?這里我們就要談到匿名函數(shù)調(diào)用問題:
匿名函數(shù)如何調(diào)用?還是上面的例子:
function a () { var b = 100; return function () { return b; }; } alert(a()); //會(huì)將整個(gè)函數(shù)體打印出來 alert(a()()); //這樣才調(diào)用了函數(shù)內(nèi)部的匿名函數(shù)
看到這里。大家應(yīng)該理解了為什么要將a()賦值給c變量了吧?因?yàn)槿绻苯邮褂胊()();這樣去調(diào)用,每次調(diào)用還是會(huì)初始化局部變量,而我們賦值給變量c,外層函數(shù)被調(diào)用了一次賦值給了C,而每次調(diào)用C去調(diào)用內(nèi)部的匿名函數(shù),從而達(dá)到了閉包。
我會(huì)在下一章繼續(xù)講閉包,歡迎大家來糾正錯(cuò)誤及指正!
Brian Lee
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/80986.html
摘要:關(guān)于循環(huán)和閉包當(dāng)循環(huán)和閉包結(jié)合在一起時(shí),經(jīng)常會(huì)產(chǎn)生讓初學(xué)者覺得匪夷所思的問題。閉包是一把雙刃劍是比較難以理解和掌握的部分,它十分強(qiáng)大,卻也有很大的缺陷,如何使用它完全取決于你自己。 在談閉包之前,我們首先要了解幾個(gè)概念: 什么是函數(shù)表達(dá)式? 與函數(shù)聲明有何不同? JavaScript查找標(biāo)識(shí)符的機(jī)制 JavaScript的作用域是詞法作用域 JavaScript的垃圾回收機(jī)制 先來...
摘要:在內(nèi)部,理所當(dāng)然能訪問到局部變量,但當(dāng)作為的返回值賦給外的全局變量時(shí),神奇的事情發(fā)生了在全局作用域中訪問到了,這就是閉包。而閉包最神奇的地方就是能在一個(gè)函數(shù)外訪問函數(shù)中的局部變量,把這些變量用閉包的形式放在函數(shù)中便能避免污染。 一、閉包是什么? 《JavaScript高級(jí)程序設(shè)計(jì)》中寫道:閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù),如果用下定義的觀點(diǎn)看,這句話就是說閉包是函數(shù),我...
摘要:函數(shù)在執(zhí)行的時(shí)候執(zhí)行函數(shù),將當(dāng)前的變量對(duì)象由于當(dāng)前的環(huán)境是函數(shù),所以將其活動(dòng)對(duì)象作為變量對(duì)象添加到作用域鏈的前端。此時(shí),由于在執(zhí)行,而作用域鏈也存在,所以可以在作用域鏈上進(jìn)行查找,去訪問的變量。 一、現(xiàn)狀 閉包是jser繞不過的坎,一直在都在說,套用 simpson 的話來說:JavaScript中閉包無處不在,你只需要能夠識(shí)別并擁抱它。 閉包是基于詞法作用域書寫代碼時(shí)的自然結(jié)果,你甚...
摘要:將作用域賦值給變量這里的作用域是,而不是將作用域賦值給一個(gè)變量閉包返回瀏覽器中內(nèi)存泄漏問題大家都知道,閉包會(huì)使變量駐留在內(nèi)存中,這也就導(dǎo)致了內(nèi)存泄漏。 上一章我們講了匿名函數(shù)和閉包,這次我們來談?wù)勯]包中作用域this的問題。 大家都知道,this對(duì)象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定的,如果this在全局就是[object window],如果在對(duì)象內(nèi)部就是指向這個(gè)對(duì)象,而閉包卻是在運(yùn)行...
摘要:接上回我寫了一篇關(guān)于閉包的博客學(xué)習(xí)之閉包,最后談到閉包導(dǎo)致的問題時(shí)留了一個(gè)尾在以下的瀏覽器中會(huì)有內(nèi)存泄漏的問題。今天的博客就繼續(xù)探索一下內(nèi)存泄漏的問題。博客地址的前端之路原文鏈接學(xué)習(xí)之內(nèi)存泄漏 接上回我寫了一篇關(guān)于閉包的博客《學(xué)習(xí)JavaScript之閉包》, 最后談到閉包導(dǎo)致的問題時(shí)留了一個(gè)尾: 在IE9以下的瀏覽器中會(huì)有內(nèi)存泄漏的問題。 今天的博客就繼續(xù)探索一下內(nèi)存泄漏的問題。 淺...
閱讀 1121·2023-04-26 02:26
閱讀 2245·2021-09-26 10:16
閱讀 1624·2019-08-30 12:57
閱讀 3532·2019-08-29 16:10
閱讀 3296·2019-08-29 13:47
閱讀 1292·2019-08-29 13:12
閱讀 2198·2019-08-29 11:11
閱讀 1398·2019-08-26 13:28