您好,登錄后才能下訂單哦!
摘要
閉包機制是JavaScript的重點和難點,本文希望能幫助大家輕松的學(xué)習(xí)閉包
一、什么是閉包?
閉包就是可以訪問另一個函數(shù)作用域中變量的函數(shù)。
下面列舉出常見的閉包實現(xiàn)方式,以例子講解閉包概念
function f1(){ var n=999; nAdd=function(){n+=1} function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999 nAdd(); result(); // 1000
f1是f2的父函數(shù),而f2被賦給了一個全局變量(return的值),這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中,不會在調(diào)用結(jié)束后,被垃圾回收機制(garbage collection)回收,這便形成了閉包。
因此,可以這么理解。閉包機制就是,如果A函數(shù)引用了另一個函數(shù)B的變量,但是B返回后A仍沒有返回,仍存在,因為A的引用,所以B的所有局部變量并不會隨B退出而注銷,會一直存在,直到A注銷。此時A就是閉包。
二、閉包的this指針
閉包通常在全局環(huán)境調(diào)用的,所以this通常指向window,具體情況還是需要視執(zhí)行環(huán)境而言,總之this指向執(zhí)行環(huán)境。
若需要閉包的this指向閉包的包含對象,則需要將包含對象的this作為變量傳進閉包。
三、使用閉包的注意點
四、解決一道閉包常見面試題
問題:
function onMyLoad(){ /* 拋出問題: 此題的目的是想每次點擊對應(yīng)目標(biāo)時彈出對應(yīng)的數(shù)字下標(biāo) 0~4,但實際是無論點擊哪個目標(biāo)都會彈出數(shù)字5 問題所在: arr 中的每一項的 onclick 均為一個函數(shù)實例(Function 對象),這個函數(shù)實例也產(chǎn)生了一個閉包域, 這個閉包域引用了外部閉包域的變量,其 function scope 的 closure 對象有個名為 i 的引用, 外部閉包域的私有變量內(nèi)容發(fā)生變化,內(nèi)部閉包域得到的值自然會發(fā)生改變 */ var arr = document.getElementsByTagName("p"); for(var i = 0; i < arr.length;i++){ arr[i].onclick = function(){ alert(i); } } }
解決方法
1、在外面再加一層函數(shù),將i作為函數(shù)參數(shù)傳進來,這樣每次保存的是函數(shù)內(nèi)部的變量,與外部i不是同一個內(nèi)存空間,而每次調(diào)用函數(shù)都會生成一個局部變量,所以可以保證每次保存的值互不影響。
for(var i = 0; i<arr.length;i++){ arr[i].onclick = (function(arg){ return function () { alert(arg); } })(i); }
2、用ES6新特let,將for循環(huán)的var i改成let i,這樣當(dāng)前的i只在本輪循環(huán)有效,所以每一次循環(huán)的i其實都是一個新的變量。你可能會問,如果每一輪循環(huán)的變量i都是重新聲明的,那它怎么知道上一輪循環(huán)的值,從而計算出本輪循環(huán)的值?這是因為 JavaScript 引擎內(nèi)部會記住上一輪循環(huán)的值,初始化本輪的變量i時,就在上一輪循環(huán)的基礎(chǔ)上進行計算。
以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持億速云!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。