一句話-作用域(變量和函數(shù)的可訪問范圍刊咳,控制變量和函數(shù)的可見性與生命周期)

Js總的采取詞法作用域,也就是靜態(tài)作用域儡司。詞法作用域是作用域在詞法分析階段就確定了娱挨,不會改變,即變量的作用域是在定義的時候而不是執(zhí)行的時候確定的作用域捕犬。作用域最大的用處就是隔離變量跷坝,不同作用域下同名變量是不會有沖突的

 詞法作用域分析1
  var value = 1;
  function foo() {
       console.log(value);//1
     }
  function bar() {
       var value = 2;
       foo();
     }
   bar();
   在執(zhí)行bar()的時候,當執(zhí)行到foo()函數(shù)的碉碉,當需要輸出value的時候柴钻,會先在他的內(nèi)部尋找是否有這個值,如果沒有就返回錯誤垢粮,尋找他的上一級作用域贴届,在此例中是全局的1,如果按照動態(tài)作用域分析的話,會輸出2.

全局作用域:在代碼的任何地方都能訪問到的對象擁有全局作用域毫蚓,全局作用域的變量是全局對象的屬性占键,不論在什么函數(shù)中都可以直接訪問

1 .最直接形式,最外層函數(shù)體聲明的變量
2 .window的所有屬性都具有全局作用域
3 .沒有使用var聲明的變量都具有全局作用域绍些,成為全局變量捞慌,所以聲明局部變量必須使用var

局部作用域:局部變量的優(yōu)先級高于全局變量(或者應(yīng)該叫做函數(shù)作用域)

1 .函數(shù)體內(nèi)使用var聲明的變量具有局部作用域,成為局部變量
2 .函數(shù)的參數(shù)也具有局部作用

  var a=3; // 全局變量  
  function fn(b){ // 局部變量  
     c=2; // 全局變量  
     var d=5; // 局部變量  
     function subFn(){  
        var e=d; // **父函數(shù)的局部變量對子函數(shù)可見**  
        for(var i=0;i<3;i++){  
          console.write(i);  
        }  
        alert(i);// 3, 在for循環(huán)內(nèi)聲明柬批,循環(huán)外function內(nèi)仍然可見啸澡,沒有塊作用域  但是使用let聲明就不一樣了。
     }  
    } 
    fn()
    console.log(c); // 在function內(nèi)聲明但不帶var修飾氮帐,仍然是全局變量 

塊級作用域

1 . let,const定義的在{}內(nèi)更加深入的一些變量

作用域鏈[[Scope]]內(nèi)部屬性嗅虏,該屬性包含了函數(shù)被創(chuàng)建的作用域中的對象的集合,這個集合被稱為函數(shù)的作用域鏈上沐,他決定了哪些數(shù)據(jù)能被函數(shù)訪問(服務(wù)于函數(shù),理解為一個數(shù)組皮服,而不是真的一條鏈)

1 .當一個函數(shù)創(chuàng)建之后,他實際上保存一個作用域鏈参咙,并且作用域鏈會被創(chuàng)建次函數(shù)的作用域中可訪問的數(shù)據(jù)對象填充龄广。

  function fun03()  
  {  
      var a = 10;  
      return function(){  
          a*= 2 ;  
          return a ;  
      };  
  }  

  var f = fun03();  
  f();  
  var x = f();  
 console.log(x);  //40  

  var g = fun03();  
  var y = g();  
  console.log(y); //20  

1 .分析

var a;
function f(){
    a=100;
}
 f()
console.log(a)//100執(zhí)行函數(shù)過后,里面的覆蓋了外面的全局變量

var a;
function fun03()  
  {  
      var a = 10; 
      a=100 
  }  

 fun03()//100只是覆蓋了里面的局部的a的值蕴侧,外面的還是undefiend
 console.log(a)//undefined

  var a;
  function fun03()  
  {  
      var a = 10; 
      return function(){  
          a*= 2 ;  
          return a;  
      };  
  } 
  var g = fun03();  
  var y = g();  
  console.log(y); //20   輸出的是整個函數(shù)的值择同,因為里面返回的是一個函數(shù),而且現(xiàn)在a的值仍然是undefiend.和上面的原理一樣净宵。


var f = fun03();  
  f();  
  var x = f();  
 console.log(x);//40上面的值被執(zhí)行了兩遍


function test(){
      var a=b=c=d=e=0;
   //除了直接接觸var的a敲才,剩下的都變成了全局變量
}

4 .參數(shù)和局部變量重名的時候,優(yōu)先級是相等的择葡。

    var a=10;
    function f(){
        console.log(a)
        var a=20;
    }
    f()//不傳參的時候為undefined

    var a=10;
    function f(a){
        console.log(a)
        var a=20;
    }
    f(a)//傳參以后10

后來

1 .在解釋的過程中紧武,js是嚴格按照作用域的機制來執(zhí)行,所以js解釋器只需要通過靜態(tài)分析就可以確定每個變量敏储,函數(shù)的作用域阻星。
2 .每個解釋器在執(zhí)行函數(shù)的時候,都會創(chuàng)建一個執(zhí)行環(huán)境已添,這個虛擬環(huán)境中先創(chuàng)建一個調(diào)用對象迫横,在這個調(diào)用對象中存儲著當前作用域中所有的局部變量,參數(shù)酝碳,嵌套函數(shù),外部作用域以及父級引用恨狈。
3 .js解釋器通過作用域鏈把多個嵌套函數(shù)作用域連接在一起疏哗,并借助這個鏈幫助了解釋器檢索變量的值,這個作用域鏈相當于一個索引表禾怠,并通過編號來存儲嵌套關(guān)系返奉。

作用域的優(yōu)先級

1 .局部變量優(yōu)先于全局變量贝搁。
2 .如果函數(shù)體內(nèi)存在同名的參數(shù)函數(shù)和局部參數(shù),函數(shù)參數(shù)優(yōu)先
3 .函數(shù)體內(nèi)有局部變量和全局變量芽偏,那么局部變量優(yōu)先雷逆。
4 .內(nèi)層函數(shù)可以訪問外層函數(shù)的局部變量,而外層函數(shù)卻不能訪問內(nèi)層函數(shù)的變量污尉,這就是變量作用域鏈膀哲。
5 .閉包函數(shù)根據(jù)定義作用域來確定自己包含變量的作用域和作用域鏈
6 .變量是對象的屬性,全局變量是window對象的屬性被碗,局部變量是調(diào)用對象的變量某宪。

管理作用域

1 .js引擎會在頁面加載后創(chuàng)建一個全局的執(zhí)行上下文,然后每執(zhí)行一個函數(shù)都會創(chuàng)建一個對應(yīng)的執(zhí)行上下文锐朴,最終機那里一個執(zhí)行上下文棧兴喂,當前起作用的執(zhí)行上下文在堆棧的最底部
2 .每個執(zhí)行上下文都有一個與之相關(guān)聯(lián)的作用域鏈,用于解析標識符焚志。作用域鏈包含一個或者多個變量對象衣迷,這些對象定義執(zhí)行了上下文作用域內(nèi)的標識符
3 .全局執(zhí)行上下文的作用域鏈中只有一個變量對象,他定義了js中所有可用的全局變量和函數(shù)酱酬。當函數(shù)被創(chuàng)建的時候壶谒,js引擎會把創(chuàng)建時執(zhí)行上下文的作用域鏈賦給函數(shù)的內(nèi)部屬性[[scope]],這個內(nèi)部屬性無法內(nèi)直接訪問。當函數(shù)執(zhí)行的時候岳悟,js引擎會創(chuàng)建一個活動對象佃迄,并在初始化的時候給this,argumets,命名參數(shù)贵少,和該函數(shù)的所有局部變量賦值呵俏。活動對象出現(xiàn)在執(zhí)行上下文作用域鏈的頂端滔灶,緊接著后面的是函數(shù)[[scope]]屬性中的對象普碎。
4 .在執(zhí)行代碼的時候,js引擎會通過搜索執(zhí)行上下文的作用域鏈來解析諸如變量和函數(shù)名這樣的標識符录平,解析標識符的過程從作用域鏈頂端開始麻车,自上而下的開始進行。
5 .標識符在作用域鏈中的位置越深斗这,查找和訪問他所需的時間就越長动猬,如果作用域管理不當,就會給腳本執(zhí)行帶來負面影響
6 .不過以上原則對于V8不是很適用表箭,因為他的優(yōu)化早已對這個無感了
7 .使用局部變量:局部變量是js中讀取最快的標識符赁咙。因為他們存在于執(zhí)行函數(shù)活動的對象中,解析符只需要查找作用域鏈中的單個對象。
8 .增長作用域鏈:with和try-catch會增長作用鏈彼水,所以不要在catch中執(zhí)行過多的代碼崔拥,來將其帶來的性能影響降到最小

高效的數(shù)據(jù)存取

1 .數(shù)據(jù)在腳本中存儲的位置直接影響腳本執(zhí)行的總耗時。
2 .字面量讀取值和局部變量讀取值的開銷差異十分的小凤覆,可以忽略不計
3 .真正的差異是在于從數(shù)組或者對象中讀取數(shù)據(jù)链瓦,一個需要索引,一個需要屬性值來查詢數(shù)據(jù)存儲的位置盯桦。
4 .始終將那些需要頻繁存取的值存儲到局部變量中慈俯。在數(shù)據(jù)村塾時,將函數(shù)中使用超過一次的兌現(xiàn)該屬性或數(shù)組元素存儲為局部變量
5 .在處理HTMLCollection對象這樣的dom方法的返回值俺附,使用局部變量特別重要肥卡,實際上每次存取這個對象,都是在對DOM文檔進行動態(tài)查詢事镣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末步鉴,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子璃哟,更是在濱河造成了極大的恐慌氛琢,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件随闪,死亡現(xiàn)場離奇詭異阳似,居然都是意外死亡,警方通過查閱死者的電腦和手機铐伴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門撮奏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人当宴,你說我怎么就攤上這事畜吊。” “怎么了户矢?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵玲献,是天一觀的道長。 經(jīng)常有香客問我梯浪,道長捌年,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任挂洛,我火速辦了婚禮礼预,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虏劲。我一直安慰自己逆瑞,他們只是感情好荠藤,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著获高,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吻育。 梳的紋絲不亂的頭發(fā)上念秧,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天,我揣著相機與錄音布疼,去河邊找鬼摊趾。 笑死,一個胖子當著我的面吹牛游两,可吹牛的內(nèi)容都是我干的砾层。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼贱案,長吁一口氣:“原來是場噩夢啊……” “哼肛炮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宝踪,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤侨糟,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后瘩燥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秕重,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年厉膀,在試婚紗的時候發(fā)現(xiàn)自己被綠了溶耘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡服鹅,死狀恐怖凳兵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情菱魔,我是刑警寧澤留荔,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站澜倦,受9級特大地震影響聚蝶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜藻治,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一碘勉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桩卵,春花似錦验靡、人聲如沸倍宾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽高职。三九已至,卻和暖如春辞州,著一層夾襖步出監(jiān)牢的瞬間怔锌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工变过, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留埃元,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓媚狰,卻偏偏與公主長得像岛杀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崭孤,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容