js 閉包深入理解與實(shí)例分析
本文實(shí)例講述了js 閉包。分享給大家供大家參考,具體如下:
1.什么是閉包
定義:是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù)
創(chuàng)建閉包:在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)
基本特點(diǎn) 在返回的匿名函數(shù)中 可以調(diào)用外部函數(shù)的變量 如下例中所示 內(nèi)部函數(shù)(匿名函數(shù)) 可以訪問外部函數(shù)的變量num 形式如a[num] 原因是匿名函數(shù)作用域鏈中包括外部函數(shù)test1的作用域
閉包有權(quán)訪問包含函數(shù)內(nèi)部的所有變量 如下面的 外部函數(shù)定義變量d 在閉包中可以直接訪問到d (var dd=d)
function test1(num){
var d;
return function(a,b){
var d1=a[num],d2=b[num];
var dd=d;
}
}
實(shí)例參考 此時(shí)點(diǎn)擊產(chǎn)品1 到 產(chǎn)品4 結(jié)果都是5 點(diǎn)擊匿名函數(shù)的作用域鏈中包括外部函數(shù)init的活動(dòng)對(duì)象 都是引用的同一個(gè)變量i 都是5 。解決辦法 返回的匿名函數(shù) 通過立即執(zhí)行函數(shù) 把參數(shù)i傳給匿名函數(shù)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>閉包演示</title>
<style type="text/css">
p {background:gold;}
</style>
<script type="text/javascript">
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = function() {
alert(i);
}
}
}
</script>
</head>
<body onload="init();">
<p>產(chǎn)品 0</p>
<p>產(chǎn)品 1</p>
<p>產(chǎn)品 2</p>
<p>產(chǎn)品 3</p>
<p>產(chǎn)品 4</p>
</body>
</html>
彈出結(jié)果都是5截圖

解決辦法:立即執(zhí)行匿名函數(shù) 參數(shù)i是循環(huán)i的值 傳遞給num形參 匿名函數(shù)里 在創(chuàng)建閉包 可以訪問這個(gè)傳遞過來的值num
pAry[i].onclick = function(num){//......}(i)
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<title>閉包演示</title>
<style type="text/css">
p {background:gold;}
</style>
<script type="text/javascript">
/*修改后*/
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = function(num) {
return function(){
alert(num)
}
}(i)
}
}
</script>
</head>
<body onload="init();">
<p>產(chǎn)品 0</p>
<p>產(chǎn)品 1</p>
<p>產(chǎn)品 2</p>
<p>產(chǎn)品 3</p>
<p>產(chǎn)品 4</p>
</body>
</html>
結(jié)果點(diǎn)擊第一展示

還有這樣寫也是可以的
function a(){
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
(function(num){
pAry[num].onclick = function() {
alert(num);
}
})(i)
}
}
1.1 閉包的原理
-1) 閉包的作用域鏈 包括 閉包自身的作用域(一般返回匿名函數(shù)的作用域),外部函數(shù)的作用域(包含的外部函數(shù)),全局作用域
-2)通常,函數(shù)的作用域和所有變量都會(huì)在函數(shù)執(zhí)行結(jié)束后被銷毀
-3)函數(shù)返回一個(gè)閉包,這個(gè)函數(shù)的作用域會(huì)一直保存在內(nèi)存中直到閉包不存在為止
使用閉包可以模仿塊級(jí)作用域
-1)創(chuàng)建閉包并立即執(zhí)行這個(gè)函數(shù) 不會(huì)再內(nèi)存中留下該函數(shù)的引用
-2 )結(jié)果 函數(shù)內(nèi)部的所有變量都會(huì)被立即銷毀
2.什么是作用域鏈
執(zhí)行環(huán)境:定義了變量或函數(shù)有權(quán)訪問其他數(shù)據(jù),決定它們各自的行為。
變量對(duì)象:每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象。
執(zhí)行環(huán)境定義的所有變量和函數(shù)都保存在變量對(duì)象中。編寫代碼無法訪問這個(gè)對(duì)象,解析器在處理數(shù)據(jù)時(shí)會(huì)在后臺(tái)使用它。
-1)全局執(zhí)行環(huán)境是最外圍的一個(gè)執(zhí)行環(huán)境
-2)web瀏覽器中,全局執(zhí)行環(huán)境默認(rèn)是window對(duì)象,因此所有全局變量和函數(shù)都是作為window對(duì)象的屬性和方法創(chuàng)建的
-3)某個(gè)執(zhí)行環(huán)境中的所有代碼執(zhí)行完畢后,該環(huán)境被銷毀,保存在其中的所有變量和函數(shù)定義都隨之銷毀 全局執(zhí)行環(huán)境直到應(yīng)用程序退出--例如關(guān)閉網(wǎng)頁或?yàn)g覽器時(shí)才會(huì)被銷毀
-4)每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境
作用域鏈:當(dāng)代碼在一個(gè)執(zhí)行環(huán)境中執(zhí)行時(shí),會(huì)創(chuàng)建變量對(duì)象 一個(gè)作用域鏈
作用域鏈用途:保證對(duì)執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問
標(biāo)識(shí)符解析:沿著作用域鏈一級(jí)一級(jí)的向上搜索標(biāo)識(shí)符的過程。
函數(shù)參數(shù)也被當(dāng)做變量來看待,因此訪問規(guī)則與執(zhí)行環(huán)境中的其它變量相同。 例子:下面函數(shù)chageColor(num){} 在閉包里tempColor(a){}里可用a[num]訪問
實(shí)例解析
<script type="text/javascript">
/*全局變量*/
var color = 'red' ;
function changeColor(num){
var otherColor = 'blue',
another =color,
chage = changeColor();
function tempColor(a){
var temp = otherColor,
temp2 = color,
temp3 = changeColor();/*這里可以訪問上層執(zhí)行環(huán)境otherColor another chage 和全局color*/
var u =a[num];
}
}
</script>
全局 window
|
|-------------color 全局變量
|------------changeColor()
|
|---------------otherColor(局部變量 還有兩個(gè)就是調(diào)用的上層全局環(huán)境里的color變量和函數(shù)chageColor)
|---------------tempColor()
|-------------------h(變量h不能被上層執(zhí)行環(huán)境調(diào)用 只能在tempColor()里調(diào)用 標(biāo)識(shí)符向上搜索沿著作用域鏈 這個(gè)環(huán)境里可以調(diào)用外層環(huán)境和全局環(huán)境的變量)
參考:
http://www.dbjr.com.cn/article/183094.htm
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《javascript面向?qū)ο笕腴T教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- JS閉包原理及其使用場(chǎng)景解析
- JavaScript 閉包的使用場(chǎng)景
- 深入了解JS之作用域和閉包
- JavaScript閉包原理與用法學(xué)習(xí)筆記
- JavaScript 函數(shù)用法詳解【函數(shù)定義、參數(shù)、綁定、作用域、閉包等】
- JavaScript閉包相關(guān)知識(shí)解析
- JS頁面獲取 session 值,作用域和閉包學(xué)習(xí)筆記
- 新手入門js閉包學(xué)習(xí)過程解析
- JS常見面試試題總結(jié)【去重、遍歷、閉包、繼承等】
- JS實(shí)現(xiàn)利用閉包判斷Dom元素和滾動(dòng)條的方向示例
- JS學(xué)習(xí)筆記之閉包小案例分析
- js核心基礎(chǔ)之閉包的應(yīng)用實(shí)例分析
- js閉包的9個(gè)使用場(chǎng)景
相關(guān)文章
Openlayers實(shí)現(xiàn)距離面積測(cè)量
這篇文章主要為大家詳細(xì)介紹了Openlayers實(shí)現(xiàn)距離面積測(cè)量,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09
JavaScript異步編程:異步數(shù)據(jù)收集的具體方法
我們先嘗試在不借助任何工具函數(shù)的情況下來解決這個(gè)問題。筆者能想到的最簡(jiǎn)單的方法是:因前一個(gè)readFile的回調(diào)運(yùn)行下一個(gè)readFile,同時(shí)跟蹤記錄迄今已觸發(fā)的回調(diào)次數(shù),并最終顯示輸出。下面是筆者的實(shí)現(xiàn)結(jié)果。2013-08-08
淺析JS中對(duì)函數(shù)function的理解(基礎(chǔ)篇)
我們知道,在js中,函數(shù)實(shí)際上是一個(gè)對(duì)象,每個(gè)函數(shù)都是Function類型的實(shí)例,并且都與其他引用類型一樣具有屬性和方法。下面給大家談下對(duì)JS中函數(shù)function的理解,一起看看吧2016-10-10
基于Unit PNG Fix.js有時(shí)候在ie6下不正常的解決辦法
本篇文章是對(duì)Unit PNG Fix.js有時(shí)候在ie6下不正常的解決辦法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
javascript閉包的高級(jí)使用方法實(shí)例
這篇文章介紹了javascript閉包的高級(jí)使用方法實(shí)例,有需要的朋友可以參考一下2013-07-07
前端uniapp封裝網(wǎng)絡(luò)請(qǐng)求以及實(shí)際應(yīng)用教程
這篇文章主要給大家介紹了關(guān)于前端uniapp封裝網(wǎng)絡(luò)請(qǐng)求以及實(shí)際應(yīng)用的相關(guān)資料,在uniapp中進(jìn)行網(wǎng)絡(luò)測(cè)試請(qǐng)求可以通過封裝網(wǎng)絡(luò)請(qǐng)求來實(shí)現(xiàn),文中給出了詳細(xì)的代碼實(shí)例,需要的朋友可以參考下2024-01-01
JavaScript?中的數(shù)據(jù)類型Number
這篇文章主要介紹了JavaScript?中的數(shù)據(jù)類型Number,Number?類型使用?IEEE?754?格式表示整數(shù)和浮點(diǎn)值,下文相關(guān)詳細(xì)資料介紹,需要的小伙伴可以參考一下2022-04-04

