通過示例徹底搞懂js閉包
例1
function sayHello(name)
{
var text = 'Hello ' + name;
var sayAlert = function() { console.log(text); }
sayAlert();
}
sayHello("Bob") // 輸出"Hello Bob"
在sayHello()函數(shù)中定義并調(diào)用了sayAlert()函數(shù);sayAlert()作為內(nèi)層函數(shù),可以訪問外層函數(shù)sayHello()中的text變量。
例2
function sayHello2(name)
{
var text = 'Hello ' + name; // 局部變量
var sayAlert = function() { console.log(text); }
return sayAlert;
}
var say2 = sayHello2("Jane");
say2(); // 輸出"Hello Jane"
例3
function buildList(list) {
var result = [];
for(var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push(
function() {
console.log(item + ' ' + list[i]);
}
);
}
return result;
}
var fnlist = buildList([1,2,3]);
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
得到的結(jié)果:連續(xù)輸出3個(gè)"item3 undefined"
解析:通過執(zhí)行buildList函數(shù),返回了一個(gè)result,那么這個(gè)result存放的是3個(gè)匿名函數(shù)。然而這三個(gè)匿名函數(shù)其實(shí)就是三個(gè)閉包,因?yàn)樗梢栽L問到父函數(shù)的局部變量。所以閉包內(nèi)的保留的i是最終的值為3.所以list[3]肯定是undefined. item變量值為item3.
改成如下代碼:
function buildList(list) {
var result = [];
for(var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push(
(function(i) {
console.log(item + ' ' + list[i]);
})(i)
);
}
return result;
}
var fnlist = buildList([1,2,3]);
得到的結(jié)果:
item1 1 item2 2 item3 3
解釋:這兒雖然傳遞了一個(gè)數(shù)組進(jìn)去,但是返回的是三個(gè)自執(zhí)行的函數(shù)。
例4
function newClosure(someNum, someRef)
{
var anArray = [1,2,3];
var num = someNum;
var ref = someRef;
return function(x)
{
num += x;
anArray.push(num);
console.log('num: ' + num + "; " + 'anArray ' + anArray.toString() + "; " + 'ref.someVar ' + ref.someVar);
}
}
closure1 = newClosure(40, {someVar: "closure 1"});
closure2 = newClosure(1000, {someVar: "closure 2"});
closure1(5); // 打印"num: 45; anArray 1,2,3,45; ref.someVar closure 1"
closure2(-10); // 打印"num: 990; anArray 1,2,3,990; ref.someVar closure 2"
每次調(diào)用newClosure()都會創(chuàng)建獨(dú)立的閉包,它們的局部變量num與ref的值并不相同。
例5
function sayAlice()
{
var sayAlert = function() { console.log(alice); }
var alice = 'Hello Alice';
return sayAlert;
}
var sayAlice2 = sayAlice();
sayAlice2(); // 輸出"Hello Alice"
alice變量在sayAlert函數(shù)之后定義,這并未影響代碼執(zhí)行。因?yàn)榉祷睾瘮?shù)sayAlice2所指向的閉包會包含sayAlice()函數(shù)中的所有局部變量,這自然包括了alice變量,因此可以正常打印”Hello Alice”。
例6
function setupSomeGlobals() {
var num = 666;
gAlertNumber = function() { console.log(num); }
gIncreaseNumber = function() { num++; }
gSetNumber = function(x) { num = x; }
}
setupSomeGlobals();
gAlertNumber(); // 輸出666
gIncreaseNumber();
gAlertNumber(); // 輸出667
gSetNumber(5);
gAlertNumber(); // 輸出5
解釋:首先gAlertNumber,gIncreaseNumber,gSetNumber是三個(gè)全局變量,并且其三個(gè)值都是匿名函數(shù),然而這三個(gè)匿名函數(shù)本身都是閉包。他們操作的num都是保存在內(nèi)存中的同一個(gè)num,所有會得出上面的結(jié)果。
以上這篇通過示例徹底搞懂js閉包就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 通俗易懂地解釋JS中的閉包
- JS繼承與閉包及JS實(shí)現(xiàn)繼承的三種方式
- 淺談JavaScript作用域和閉包
- JS閉包的幾種常見形式實(shí)例詳解
- JS實(shí)現(xiàn)閉包中的沙箱模式示例
- JavaScript閉包的簡單應(yīng)用
- JavaScript閉包和回調(diào)詳解
- 淺談JS封閉函數(shù)、閉包、內(nèi)置對象
- JavaScript閉包_動力節(jié)點(diǎn)Java學(xué)院整理
- 深入理解Javascript中的作用域鏈和閉包
- JS閉包可被利用的常見場景小結(jié)
- 利用js的閉包原理做對象封裝及調(diào)用方法
- javascript閉包功能與用法實(shí)例分析
- JavaScript中閉包的詳解
- JS閉包用法實(shí)例分析
- 圖解Javascript——作用域、作用域鏈、閉包
- 輕松理解JavaScript閉包
- js中的閉包學(xué)習(xí)心得
相關(guān)文章
創(chuàng)建一個(gè)類Person的簡單實(shí)例
如何創(chuàng)建一個(gè)類Person?下面小編就為大家?guī)硪黄獎(jiǎng)?chuàng)建一個(gè)類Person的簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考,一起跟隨小編過來看看吧2016-05-05
JavaScript中7種位運(yùn)算符在實(shí)戰(zhàn)的妙用
位運(yùn)算是在數(shù)字底層(即表示數(shù)字的 32 個(gè)數(shù)位)進(jìn)行運(yùn)算的,下面這篇文章主要給大家介紹了關(guān)于JavaScript中7種位運(yùn)算符在實(shí)戰(zhàn)的妙用,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
純js實(shí)現(xiàn)頁面返回頂部的動畫(超簡單)
下面小編就為大家?guī)硪黄僯s實(shí)現(xiàn)頁面返回頂部的動畫(超簡單)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08
layer ui插件顯示tips時(shí),修改字體顏色的實(shí)現(xiàn)方法
今天小編就為大家分享一篇layer ui插件顯示tips時(shí),修改字體顏色的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09
Web性能優(yōu)化系列 10個(gè)提升JavaScript性能的技巧
Javascript 性能優(yōu)化絕不是一種書面的技術(shù),Nicholas 的技術(shù)演進(jìn)列出了10條建議,幫助你寫出高效的 JS 代碼2016-09-09
Bootstrap模態(tài)框調(diào)用功能實(shí)現(xiàn)方法
這篇文章主要介紹了Bootstrap模態(tài)框調(diào)用功能實(shí)現(xiàn)方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-09-09

