js進(jìn)階學(xué)習(xí)筆記(二) -- 作用域以及變量提升

一 初步了解作用域

在了解作用域之前,先來看一個問題;
var xixi= 222;在js處理這句話的時候,會發(fā)生什么呢?

  • 參與這句代碼處理過程的參與者
    作用域參與.jpg
  • 代碼處理過程
    過程.jpg
  • 作用域是什么呢

    我們將作用域定義為一套規(guī)則,用來管理引擎是如何在當(dāng)前作用域以及嵌套的子作用域中根據(jù)標(biāo)識符名稱進(jìn)行變量查找.

  • 作用域嵌套
    • 當(dāng)一個函數(shù)嵌套在另一個函數(shù)中的時候,就發(fā)生了作用域的嵌套,因此,在當(dāng)前作用域中無法找到某個變量的時候,引擎就會在外層嵌套的作用域中繼續(xù)查找,直到找到該變量,或者到達(dá)最外層作用域.

    • 將作用域鏈比作建筑的話:一樓就代表當(dāng)前的作用域,如果找不到變量,就會往上爬樓,依次尋找變量,直到最頂層仍找不到變量的話,就會報出錯誤.


      作用域鏈.jpg

二 函數(shù)作用域

  • 定義

    可以將內(nèi)部的變量和函數(shù)定義隱藏起來,外部作用域無法訪問包裝函數(shù)內(nèi)部的任何內(nèi)容
    如果外部有一個變量xi,但是在函數(shù)作用域中也想用這個名字該怎么辦呢?

    var xi = '外部';
    function foo(){
        var xi = '內(nèi)部';
        console.log(xi)  //'內(nèi)部'
    }
    foo()
    console.log(xi);   //'外部'
    

    但是所定義的變量foo可能污染了它當(dāng)前所在的作用域,且執(zhí)行這個函數(shù),必須要再加一行代碼foo()來調(diào)用;優(yōu)化一下;

    var xi = '外部';
    (function foo(){
       var xi = '內(nèi)部';
       console.log(xi)  //'內(nèi)部'
    })()
    console.log(xi);   //'外部'
    

    如果我們想在內(nèi)部也訪問外部的相同變量,該怎么區(qū)分和訪問呢?

var xi = '外部';
(function foo(global){//這里可以將后面?zhèn)鱽淼膮?shù)重新命名;
var xi = '內(nèi)部';
console.log(xi) //'內(nèi)部'
console.log(global.xi) //內(nèi)部
})(window) //這里只要把window對象作為一個參數(shù)傳給封裝函數(shù)就行了.
console.log(xi); //'外部'

  **很多框架源碼都用了這個方式來解決諸如防止undefined被篡改等情況**
  **函數(shù)是js中最常見的作用域單元**
  
###三 提升
直覺上,我們會認(rèn)為js在執(zhí)行代碼的時候是由上到下一步一步執(zhí)行的,但是實際上并不完全是這樣
我們先看看一段代碼
```java
a = 2;
var a;
console.log(a); //2

這句話的代碼等同于

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

再來看一段代碼:

console.log(a);//undefined
var a = 2;

這段代碼等同于:

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

在這段代碼里到底發(fā)生了什么呢?

  • 編譯器

js的作用域基本上都是詞法作用域;什么是詞法作用域呢?就是定義在詞法階段的作用域,是由你在寫代碼的時候?qū)⒆兞亢妥饔糜驅(qū)懺谀膩頉Q定的.大部分情況下詞法作用域是不變的.

我們之前提到過,編譯器第一個工作就是把代碼解析成詞法單元,然后語法分析成語法樹;在這期間,編譯器基本能夠知道標(biāo)識符是在哪聲明以及是怎么聲明的.它會用合適的作用域?qū)⑺麄冴P(guān)聯(lián)起來.
作用域編譯.jpg

回到我們剛剛的代碼;

 console.log(a);//undefined
 var a = 2;

在編譯階段,會執(zhí)行var a;;剩余的a = 2會留在原地等待執(zhí)行;因此等同于

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

在這個階段,變量聲明會從他們代碼所在的位置移動到最頂層更,這個過程就叫做提升;

  • 函數(shù)優(yōu)先

函數(shù)聲明和變量聲明都會被提升,但是,函數(shù)會首先被提升.然后才是變量;(值得注意的是,函數(shù)聲明提升的時候,函數(shù)體一同被提升;函數(shù)表達(dá)式的函數(shù)體則不提升;)

foo(); // 1
var foo;//盡管此變量聲明在function foo()之前,但是因為函數(shù)優(yōu)先
//foo變量聲明就會變成重復(fù)聲明,忽略;
function foo(){
console.log(1);
}
foo = function(){
console.log(2);
}

這段代碼會被引擎理解為:

function foo(){
console.log(1)
}
foo();
foo = function(){
console.log(2)
}

雖然var重復(fù)聲明會被忽略,但是后面的函數(shù)聲明會覆蓋前面的

foo(); // 3
function foo(){
    console.log(1);
}
var foo = function(){
    console.log(2);
}
function foo(){ //覆蓋了之前的function foo();
    console.log(3);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市构订,隨后出現(xiàn)的幾起案子梳玫,更是在濱河造成了極大的恐慌,老刑警劉巖盲赊,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碟渺,死亡現(xiàn)場離奇詭異叔扼,居然都是意外死亡,警方通過查閱死者的電腦和手機姚建,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門矫俺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人掸冤,你說我怎么就攤上這事厘托。” “怎么了稿湿?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵铅匹,是天一觀的道長。 經(jīng)常有香客問我饺藤,道長包斑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任涕俗,我火速辦了婚禮罗丰,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘再姑。我一直安慰自己萌抵,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布元镀。 她就那樣靜靜地躺著绍填,像睡著了一般。 火紅的嫁衣襯著肌膚如雪栖疑。 梳的紋絲不亂的頭發(fā)上讨永,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音遇革,去河邊找鬼卿闹。 笑死揭糕,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的比原。 我是一名探鬼主播插佛,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼量窘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起氢拥,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤蚌铜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嫩海,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冬殃,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年叁怪,在試婚紗的時候發(fā)現(xiàn)自己被綠了审葬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡奕谭,死狀恐怖涣觉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情血柳,我是刑警寧澤官册,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站难捌,受9級特大地震影響膝宁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜根吁,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一员淫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧击敌,春花似錦介返、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至轰枝,卻和暖如春晓避,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卡者。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工阻塑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留从隆,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓缭裆,卻偏偏與公主長得像键闺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子澈驼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

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

  • You don't KnowJS 引語:你不懂的JS這本書?github上已經(jīng)有了7w的star最近也是張野大大給...
    Sleet閱讀 578評論 0 0
  • 一缝其、理解js作用域 1挎塌、作用域:作用域是一套規(guī)則,用于確定在何處以及如何查找變量(標(biāo)字符)内边。2榴都、LHS查詢:查找的...
    懷念不能閱讀 457評論 0 1
  • 1.函數(shù)聲明和函數(shù)表達(dá)式有什么區(qū)別 (*) 區(qū)別: 函數(shù)聲明后面的分號可加可不加,不加也不影響接下來語句的執(zhí)行漠其,但...
    Sheldon_Yee閱讀 396評論 0 1
  • 此文章著作權(quán)歸饑人谷_Lyndon和饑人谷所有和屎,轉(zhuǎn)載請注明 前言 比較繞的并不是作用域與變量提升拴驮,而是作用域鏈,經(jīng)...
    HungerLyndon閱讀 3,049評論 4 13
  • 無論提到李叔同還是弘一法師,恐怕世人都不會陌生颠印。能夠做到俗名和法號都為人熟知纲岭,在高僧大德里應(yīng)該也相當(dāng)少見了。 弘一...
    虛度_色受想行識閱讀 4,520評論 0 23