成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

老生常談—Javascript作用域、變量提升、閉包

zhiwei / 3039人閱讀

摘要:局部變量在函數(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)存消耗大,別濫用

閉包在實(shí)際開發(fā)中的使用

??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)于let的隨想

    摘要:塊狀作用域提起中的關(guān)鍵字,第一個想法就是塊狀作用域。而如果通過這些關(guān)鍵詞聲明的,那么也就會聲明到所在的作用域中。終于回到可以將變量綁定到所在的任意作用域中,通常是內(nèi)部。避免不必要的出現(xiàn)。 讀,想到哪里寫到哪里。。。 塊狀作用域 提起ES6中的let關(guān)鍵字,第一個想法就是塊狀作用域。 說到作用域,以前提及的都是全局作用域和函數(shù)作用域。當(dāng)進(jìn)行作用域查找的時候,永遠(yuǎn)是一層一層往上查找,直到找...

    zhangwang 評論0 收藏0
  • Javascript作用變量提升

    摘要:有何區(qū)別在中,存在關(guān)鍵字,它聲明的變量同樣存在塊級作用域。而且函數(shù)本身的作用域,只存在其所在的塊級作用域之內(nèi),例如重復(fù)聲明一次函數(shù)上面這段代碼在中的輸出結(jié)果為因?yàn)楸粭l件語句中的上升覆蓋了。如果對的使用,或的其他新特性感興趣,請自行閱讀文檔。 引子 首先大家看一下下面的代碼,猜猜會輸出什么結(jié)果? var foo = 1; function bar() { if (!foo) { ...

    whlong 評論0 收藏0
  • Effective JavaScript讀書筆記(二)

    摘要:盡可能的使用局部變量,少用全局變量。正確的實(shí)現(xiàn)就是在函數(shù)體內(nèi)部使用將聲明成局部變量。在新特性中,引入了塊級作用域這個概念,因此還可以使用,來聲明局部變量。它們共享外部變量,并且閉包還可以更新的值。 變量作用域 作用域,對于JavaScript語言來說無處不在,變量作用域,函數(shù)作用域(運(yùn)行時上下文和定義時上下文),作用域污染等等都跟作用域息息相關(guān),掌握J(rèn)avaScript作用于規(guī)則,可以...

    Yuqi 評論0 收藏0
  • 老生常談閉包(你不可不知的若干知識點(diǎn))

    摘要:閉包是什么這是一個在面試的過程中出現(xiàn)的概率為以上的問題,也是我們張口就來的問題。文章推薦我們面試中在被問到閉包這個問題是要注意的幾點(diǎn)閉包的延伸,讓面試變得 閉包是什么?這是一個在面試的過程中出現(xiàn)的概率為60%以上的問題,也是我們張口就來的問題。但是我們往往發(fā)現(xiàn),在面試的過程中我們的回答并不那么讓面試官滿意,我們雖然能張口說出一些但是卻不能系統(tǒng)的對這個問題進(jìn)行回答。面試官希望加入自己團(tuán)隊(duì)...

    daydream 評論0 收藏0
  • Node.js內(nèi)存管理和V8垃圾回收機(jī)制

    摘要:垃圾回收內(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:...

    JowayYoung 評論0 收藏0

發(fā)表評論

0條評論

zhiwei

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<