摘要:的變量作用域是基于其特有的作用域鏈的。需要注意的是,用創(chuàng)建的函數(shù),其作用域指向全局作用域。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。
作用域 定義
在編程語言中,作用域控制著變量與參數(shù)的可見性及生命周期,它能減少名稱沖突,而且提供了自動(dòng)內(nèi)存管理 --javascript 語言精粹
我理解的是,一個(gè)變量、函數(shù)或者成員可以在代碼中訪問到的范圍。
js的變量作用域是基于其特有的作用域鏈的。
全局變量都是window對象的屬性
沒有塊級作用域
函數(shù)中聲明的變量在整個(gè)函數(shù)中都有定義。
//全局作用域 var a = 10; //沒有塊級作用域 if(fasle){ var b =2; } //函數(shù)作用域 function f(){ var a = 1; console.log(a); }作用域鏈
作用域鏈?zhǔn)且粋€(gè)對象列表,上下文代碼中出現(xiàn)的標(biāo)識符在這個(gè)列表中進(jìn)行查找。
如果一個(gè)變量在函數(shù)自身的作用域(在自身的變量/活動(dòng)對象)中沒有找到,那么將會查找它父函數(shù)(外層函數(shù))的變量對象,以此類推。
舉個(gè)栗子:
function f (){ var x =100; function g(){ console.log(x); } g(); } f();
這里形成了一條作用域鏈,當(dāng)函數(shù)g訪問不到變量時(shí),它會通過內(nèi)部的[[scope]]對象查找作用域鏈上的執(zhí)行上下文,當(dāng)找到就終止,找不到會繼續(xù),直到window對象上也沒有的時(shí)候,會報(bào)錯(cuò)。
需要注意的是,用new Function創(chuàng)建的函數(shù),其作用域指向全局作用域。
function f(){ var x = 100; // g.[[scope]] == window var g = new Function("", "alert(x)"); g(); } f(); //報(bào)錯(cuò) x is not defined閉包 閉包的含義
在計(jì)算機(jī)科學(xué)中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數(shù)閉包(function closures),是引用了自由變量的函數(shù)。這個(gè)被引用的自由變量將和這個(gè)函數(shù)一同存在,即使已經(jīng)離開了創(chuàng)造它的環(huán)境也不例外。所以,有另一種說法認(rèn)為閉包是由函數(shù)和與其相關(guān)的引用環(huán)境組合而成的實(shí)體。--維基百科
我的理解就是,一個(gè)函數(shù)捕獲其父函數(shù)的自由變量,這就形成了閉包。
栗子:
function f1(){ var a = 10; var b = 20; return function f2(){ console.log(a); } } var result = f1(); result();閉包的本質(zhì)
作用域鏈的存在
閉包的好處減少全局變量
減少傳遞給函數(shù)的參數(shù)數(shù)量
封裝
使用閉包的注意點(diǎn)
對捕獲的變量只是個(gè)引用,不是復(fù)制
function f(){ var num = 1; function g(){ alert(num); } num++; g(); //2 } f();
父函數(shù)每調(diào)用一次,會產(chǎn)生不同的閉包
function f(){ var num = 1; return function(){ num++; alert(num); } } var result1 =f(); result1(); result1(); var result2 =f(); result2(); result2(); //兩次都彈出一樣的數(shù)值
循環(huán)中出現(xiàn)的問題
for (var i = 1; i <= 3; i++) { var ele = document.getElementById(i); ele.onclick = function(){ alert(i); } }; // i為4
解決方法:
for (var i = 1; i <= 3; i++) { var ele = document.getElementById(i); ele.onclick = (function(id){ return function(){ alert(id); }})(i); }; // 1,2,3
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/86450.html
摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對方法,包括,,。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸?,因此文中只看懂?8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...
摘要:類的繼承建立繼承關(guān)系修改的指向調(diào)用父類方法調(diào)用父類的構(gòu)造器調(diào)用父類上的方法封裝命名空間是沒有命名空間的,因此可以用對象模擬。參考資料面向?qū)ο? 面向?qū)ο蟪绦蛟O(shè)計(jì)(Object-oriented programming,OOP)是一種程序設(shè)計(jì)范型,同時(shí)也是一種程序開發(fā)的方法。對象指的是類的實(shí)例。它將對象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴(kuò)展性?!S基百...
摘要:而閉包卻能阻止這件事情發(fā)生。由于的聲明位置使它擁有涵蓋內(nèi)部作用域的閉包,使得該作用域能夠一直存在,以供在之后進(jìn)行引用。到這里,小菊花課堂之閉包的內(nèi)容就告一段落啦,感謝各位能耐心看到這里。 由于前段時(shí)間項(xiàng)目沒有那么忙,然后我這人一天不看點(diǎn)啥就非常焦慮,于是二刷《你不知道的JavaScript》,現(xiàn)在讀到閉包,想著看完這一章節(jié),寫點(diǎn)東西也是挺好的,所以有了下面的內(nèi)容,如有不對的地方,敬請斧...
摘要:在構(gòu)造函數(shù)中的中定義的屬性和方法,會被創(chuàng)建的對象所繼承下來。從上面的輸出結(jié)果看出,指向了其構(gòu)造函數(shù)的,而本身也是一個(gè)對象,其內(nèi)部也有屬性,其指向的是直到最后指向,這條原型鏈才結(jié)束。和都指向,說明原型鏈到終止。 prototype原型對象 每個(gè)函數(shù)都有一個(gè)默認(rèn)的prototype屬性,其實(shí)際上還是一個(gè)對象,如果被用在繼承中,姑且叫做原型對象。 在構(gòu)造函數(shù)中的prototype中定義的屬性...
摘要:了解面向?qū)ο缶幊讨?,首先要了解的?zhí)行順序。的解析過程分為兩個(gè)階段預(yù)處理階段與執(zhí)行期。在執(zhí)行階段的執(zhí)行上下文對象由賦值為指向?qū)?yīng)函數(shù) 了解js面向?qū)ο缶幊讨?,首先要了解js的執(zhí)行順序。js的解析過程分為兩個(gè)階段:預(yù)處理階段與執(zhí)行期。 預(yù)處理階段 在預(yù)處理階段,js會首先創(chuàng)建一個(gè)執(zhí)行上下文對象(Execute Context,然后掃描聲明式函數(shù)和用var定義的變量,將其加入執(zhí)行上下文環(huán)...
閱讀 3082·2021-11-24 10:34
閱讀 3339·2021-11-22 13:53
閱讀 2643·2021-11-22 12:03
閱讀 3611·2021-09-26 09:47
閱讀 3020·2021-09-23 11:21
閱讀 4825·2021-09-22 15:08
閱讀 3308·2021-07-23 10:59
閱讀 1271·2019-08-29 18:31