成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

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

zhiwei / 3063人閱讀

摘要:局部變量在函數(shù)中聲明的變量,函數(shù)的參數(shù)作用域是局部性的,在函數(shù)體外,或者說(shuō)的當(dāng)前作用域的上層是無(wú)法直接讀取的。執(zhí)行結(jié)果這樣我們就在外層取得了函數(shù)內(nèi)部局部變量的也就是閉包實(shí)現(xiàn)從外部讀取局部變量的能力。

淺談作用域

??當(dāng)我們新建一個(gè)可以儲(chǔ)存變量的值,怎么才能讀取到這個(gè)變量呢?能訪問(wèn)到這個(gè)變量,就說(shuō)明符合作用域規(guī)則,作用域規(guī)則就可以說(shuō)是js引擎讀取變量的規(guī)則。
??在js中變量分為兩種,全局變量和局部變量,全局變量(擁有全局作用域)可以在整個(gè)js應(yīng)用中被所有代碼訪問(wèn)到,從程序開始分配內(nèi)存直至結(jié)束才會(huì)被釋放(出于對(duì)代碼的性能、可讀性、以及潛在沖突考慮應(yīng)該減少使用)。
??局部變量在函數(shù)中聲明的變量,函數(shù)的參數(shù)(作用域是局部性的),在函數(shù)體外,或者說(shuō)的當(dāng)前作用域的上層是無(wú)法直接讀取的。
??下面再說(shuō)下作用域嵌套,產(chǎn)生作用域鏈的事,在我們實(shí)際編寫代碼的時(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í)行的時(shí)候,會(huì)從當(dāng)前的執(zhí)行作用域開始查找變量,如果找不到,就繼續(xù)向上一級(jí)繼續(xù)查找,如果找到則會(huì)停止,如果沒有就會(huì)繼續(xù)直至當(dāng)最后到達(dá)全局作用域時(shí),此時(shí)無(wú)論找到還是沒找到,都會(huì)結(jié)束查找。

st=>start: 當(dāng)前作用域 
io1=>start: 上層作用域
io2=>start: ...
cond=>end: 全局作用域

st->io1->io2->cond 

??(簡(jiǎn)單寫了個(gè)流程圖方便腦補(bǔ)

??接下來(lái)還是這段代碼讓我們來(lái)做一個(gè)小小的修改。

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)行時(shí)所處的最內(nèi)部作用域開始,逐漸向外層查找,當(dāng)遇到第一個(gè)符合條件的結(jié)果就會(huì)返回,停止查找。

變量提升

??先簡(jiǎn)單上一段代碼

  a = "a";
  var a;
  console.log(a);

執(zhí)行結(jié)果:
??為什么會(huì)有這種結(jié)果呢?聲明在后,反而打印出前面聲明得值,其實(shí)js在編譯的時(shí)候會(huì)先進(jìn)行聲明操作,之后再進(jìn)行賦值操作,也就是只要是在作用域中的聲明一出現(xiàn),就將在代碼本身被執(zhí)行前優(yōu)先進(jìn)行處理。也可以將這個(gè)過(guò)程理解為所有的聲明(變量和函數(shù))都會(huì)被“提升”到作用域的最頂端。(雖然函數(shù)聲明和變量聲明都會(huì)被提升,但是函數(shù)優(yōu)先級(jí)要高于變量

在ES6引入了let和const可以用來(lái)聲明創(chuàng)建塊作用域。for循環(huán)頭部定義強(qiáng)烈建議用let,感興趣的人可以去看看js函數(shù)作用域和塊作用域

閉包

??提到閉包很多人腦袋里都會(huì)感覺模模糊糊的,閉包在概念上定義是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),在中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取這個(gè)函數(shù)局部變量,這時(shí)候前面說(shuō)的作用域起到作用了,所以我們現(xiàn)在可以這樣理解,定義在一個(gè)函數(shù)內(nèi)部的函數(shù),這個(gè)函數(shù)可以訪問(wèn)其他函數(shù)的變量,就可以稱為“閉包”。
??下面來(lái)聊聊閉包的用處,主要就是。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)從外部讀取局部變量的能力。
??下面說(shuō)一說(shuō)讓變量始終保存在內(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,這就說(shuō)明第一次運(yùn)行結(jié)束后啊,沒有被回收,因?yàn)閜rint()仍在使用這個(gè)作用域所以demo不會(huì)被回收。
閉包會(huì)使得對(duì)應(yīng)的變量一直保存在內(nèi)存中,不會(huì)被清理回收,對(duì)內(nèi)存消耗大,別濫用

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

??1.原生的setTimeout傳遞的函數(shù)不能帶參數(shù)

//會(huì)報(bào)錯(cuò)
function func(param){
  console.log(param);
}
var test = func(1);
setTimeout(test, 1000);


//通過(guò)閉包實(shí)現(xiàn)傳參效果
function func(param){
  return function(){
    console.log(param);
  }
}

var test = func(1);
setTimeout(test, 1000);

??2.封裝變量

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/102721.html

相關(guān)文章

  • 關(guān)于let的隨想

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

    zhangwang 評(píng)論0 收藏0
  • Javascript作用變量提升

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

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

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

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

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

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

    摘要:垃圾回收內(nèi)存管理實(shí)踐先通過(guò)一個(gè)來(lái)看看在中進(jìn)行垃圾回收的過(guò)程是怎樣的內(nèi)存泄漏識(shí)別在環(huán)境里提供了方法用來(lái)查看當(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 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

zhiwei

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<