摘要:局部變量在函數(shù)中聲明的變量,函數(shù)的參數(shù)作用域是局部性的,在函數(shù)體外,或者說的當(dāng)前作用域的上層是無法直接讀取的。執(zhí)行結(jié)果這樣我們就在外層取得了函數(shù)內(nèi)部局部變量的也就是閉包實(shí)現(xiàn)從外部讀取局部變量的能力。
淺談作用域
??當(dāng)我們新建一個可以儲存變量的值,怎么才能讀取到這個變量呢?能訪問到這個變量,就說明符合作用域規(guī)則,作用域規(guī)則就可以說是js引擎讀取變量的規(guī)則。
??在js中變量分為兩種,全局變量和局部變量,全局變量(擁有全局作用域)可以在整個js應(yīng)用中被所有代碼訪問到,從程序開始分配內(nèi)存直至結(jié)束才會被釋放(出于對代碼的性能、可讀性、以及潛在沖突考慮應(yīng)該減少使用)。
??局部變量在函數(shù)中聲明的變量,函數(shù)的參數(shù)(作用域是局部性的),在函數(shù)體外,或者說的當(dāng)前作用域的上層是無法直接讀取的。
??下面再說下作用域嵌套,產(chǎn)生作用域鏈的事,在我們實(shí)際編寫代碼的時候,比如:
var a = "a"; function demo(b) { let c = "c"; function print(c) { console.log(a + " " + b + " " + c); } print(c); } demo("b");
執(zhí)行結(jié)果:
??在print方法執(zhí)行的時候,會從當(dāng)前的執(zhí)行作用域開始查找變量,如果找不到,就繼續(xù)向上一級繼續(xù)查找,如果找到則會停止,如果沒有就會繼續(xù)直至當(dāng)最后到達(dá)全局作用域時,此時無論找到還是沒找到,都會結(jié)束查找。
st=>start: 當(dāng)前作用域 io1=>start: 上層作用域 io2=>start: ... cond=>end: 全局作用域 st->io1->io2->cond
??(簡單寫了個流程圖方便腦補(bǔ))
??接下來還是這段代碼讓我們來做一個小小的修改。
var a = "a"; function demo(b) { let c = "c", a = "d"; function print(c) { console.log(a + " " + b + " " + c); } print(c); } demo("b");
執(zhí)行結(jié)果:
??結(jié)果是輸出了上一層的變量a,這也就是作用域查找的機(jī)制,作用域始終從運(yùn)行時所處的最內(nèi)部作用域開始,逐漸向外層查找,當(dāng)遇到第一個符合條件的結(jié)果就會返回,停止查找。
變量提升??先簡單上一段代碼
a = "a"; var a; console.log(a);
執(zhí)行結(jié)果:
??為什么會有這種結(jié)果呢?聲明在后,反而打印出前面聲明得值,其實(shí)js在編譯的時候會先進(jìn)行聲明操作,之后再進(jìn)行賦值操作,也就是只要是在作用域中的聲明一出現(xiàn),就將在代碼本身被執(zhí)行前優(yōu)先進(jìn)行處理。也可以將這個過程理解為所有的聲明(變量和函數(shù))都會被“提升”到作用域的最頂端。(雖然函數(shù)聲明和變量聲明都會被提升,但是函數(shù)優(yōu)先級要高于變量)
(在ES6引入了let和const可以用來聲明創(chuàng)建塊作用域。for循環(huán)頭部定義強(qiáng)烈建議用let,感興趣的人可以去看看js函數(shù)作用域和塊作用域)
閉包??提到閉包很多人腦袋里都會感覺模模糊糊的,閉包在概念上定義是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),在中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取這個函數(shù)局部變量,這時候前面說的作用域起到作用了,所以我們現(xiàn)在可以這樣理解,定義在一個函數(shù)內(nèi)部的函數(shù),這個函數(shù)可以訪問其他函數(shù)的變量,就可以稱為“閉包”。
??下面來聊聊閉包的用處,主要就是。1.能夠讀取到函數(shù)內(nèi)部的變量,2.可以讓變量始終保存在內(nèi)存中(這點(diǎn)要注意后面解釋),下面上代碼。
function demo() { let a = "a"; function print() { console.log(a); } return print; } var clo = demo(); clo();
執(zhí)行結(jié)果:
??這樣我們就在外層取得了demo函數(shù)內(nèi)部局部變量的a,也就是閉包實(shí)現(xiàn)從外部讀取局部變量的能力。
??下面說一說讓變量始終保存在內(nèi)存中這點(diǎn).
function demo() { let a = 1; addA = () => a+=1; function print() { console.log(a); } return print; } var clo = demo(); clo(); addA(); clo();
執(zhí)行結(jié)果:
??閉包可以阻止,demo內(nèi)部作用域都被垃圾清理機(jī)制回收銷毀,可以看到局部變量a第二次執(zhí)行比第一次+1,這就說明第一次運(yùn)行結(jié)束后啊,沒有被回收,因?yàn)閜rint()仍在使用這個作用域所以demo不會被回收。
(閉包會使得對應(yīng)的變量一直保存在內(nèi)存中,不會被清理回收,對內(nèi)存消耗大,別濫用)
??1.原生的setTimeout傳遞的函數(shù)不能帶參數(shù)
//會報錯 function func(param){ console.log(param); } var test = func(1); setTimeout(test, 1000); //通過閉包實(shí)現(xiàn)傳參效果 function func(param){ return function(){ console.log(param); } } var test = func(1); setTimeout(test, 1000);
??2.封裝變量
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102721.html
摘要:塊狀作用域提起中的關(guān)鍵字,第一個想法就是塊狀作用域。而如果通過這些關(guān)鍵詞聲明的,那么也就會聲明到所在的作用域中。終于回到可以將變量綁定到所在的任意作用域中,通常是內(nèi)部。避免不必要的出現(xiàn)。 讀,想到哪里寫到哪里。。。 塊狀作用域 提起ES6中的let關(guān)鍵字,第一個想法就是塊狀作用域。 說到作用域,以前提及的都是全局作用域和函數(shù)作用域。當(dāng)進(jìn)行作用域查找的時候,永遠(yuǎn)是一層一層往上查找,直到找...
摘要:有何區(qū)別在中,存在關(guān)鍵字,它聲明的變量同樣存在塊級作用域。而且函數(shù)本身的作用域,只存在其所在的塊級作用域之內(nèi),例如重復(fù)聲明一次函數(shù)上面這段代碼在中的輸出結(jié)果為因?yàn)楸粭l件語句中的上升覆蓋了。如果對的使用,或的其他新特性感興趣,請自行閱讀文檔。 引子 首先大家看一下下面的代碼,猜猜會輸出什么結(jié)果? var foo = 1; function bar() { if (!foo) { ...
摘要:盡可能的使用局部變量,少用全局變量。正確的實(shí)現(xiàn)就是在函數(shù)體內(nèi)部使用將聲明成局部變量。在新特性中,引入了塊級作用域這個概念,因此還可以使用,來聲明局部變量。它們共享外部變量,并且閉包還可以更新的值。 變量作用域 作用域,對于JavaScript語言來說無處不在,變量作用域,函數(shù)作用域(運(yùn)行時上下文和定義時上下文),作用域污染等等都跟作用域息息相關(guān),掌握J(rèn)avaScript作用于規(guī)則,可以...
摘要:閉包是什么這是一個在面試的過程中出現(xiàn)的概率為以上的問題,也是我們張口就來的問題。文章推薦我們面試中在被問到閉包這個問題是要注意的幾點(diǎn)閉包的延伸,讓面試變得 閉包是什么?這是一個在面試的過程中出現(xiàn)的概率為60%以上的問題,也是我們張口就來的問題。但是我們往往發(fā)現(xiàn),在面試的過程中我們的回答并不那么讓面試官滿意,我們雖然能張口說出一些但是卻不能系統(tǒng)的對這個問題進(jìn)行回答。面試官希望加入自己團(tuán)隊(duì)...
摘要:垃圾回收內(nèi)存管理實(shí)踐先通過一個來看看在中進(jìn)行垃圾回收的過程是怎樣的內(nèi)存泄漏識別在環(huán)境里提供了方法用來查看當(dāng)前進(jìn)程內(nèi)存使用情況,單位為字節(jié)中保存的進(jìn)程占用的內(nèi)存部分,包括代碼本身?xiàng)6选? showImg(https://segmentfault.com/img/remote/1460000019894672?w=640&h=426);作者 | 五月君Node.js 技術(shù)棧 | https:...
閱讀 1572·2023-04-26 00:25
閱讀 950·2021-09-27 13:36
閱讀 956·2019-08-30 14:14
閱讀 2208·2019-08-29 17:10
閱讀 1035·2019-08-29 15:09
閱讀 1974·2019-08-28 18:21
閱讀 996·2019-08-26 13:27
閱讀 999·2019-08-26 10:58