js(四):提升

timg.jpg

看到這里,我相信你已經(jīng)知道了作用域的概念了,以及根據(jù)聲明的位置和方式將變量分配給作用域的相關(guān)原理了。函數(shù)作用域和塊作用域的行為是一樣的,可以總結(jié)為:任何聲明在某個(gè)作用域內(nèi)的變量,都將附屬于這個(gè)作用域。

首先我們上個(gè)例子

console.log(a);
console.log(foo);
var a=1;

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

如果你還不知道答案或者不確定,那我相信下面的內(nèi)容一定會(huì)讓你有收獲。首先我們來(lái)回顧一下作用域的一些知識(shí),引擎會(huì)在解釋JavaScript 代碼之前首先對(duì)其進(jìn)行編譯。編譯階段中的一部分工作就是找到所有的聲明,并用合適的作用域?qū)⑺鼈冴P(guān)聯(lián)起來(lái)。也就是詞法作用域的核心,所以包含所有聲明的變量或者聲明的函數(shù)在執(zhí)行之前都會(huì)先被處理。

var a=1;
比如聲明一個(gè)變量并賦值為1,表面上看只是一個(gè)聲明,實(shí)際上。js會(huì)看處理成兩個(gè)聲明,var a和a=1,第一個(gè)定義聲明是在編譯階段進(jìn)行的。第二個(gè)賦值聲明會(huì)被留在原地等待執(zhí)行階段。

var a     //編譯階段
a=1      //代碼執(zhí)行階段

也就是變量和函數(shù)感覺(jué)在執(zhí)行之前已經(jīng)被處理過(guò)了,這個(gè)過(guò)程就好像變量和函數(shù)聲明從它們?cè)诖a中出現(xiàn)的位置被“移動(dòng)”到了最上面。這個(gè)過(guò)程就叫作提升。但是要牢牢記?。褐挥斜宦暶鞯暮瘮?shù)或者變量才會(huì)被提升,也就是只有聲明本身會(huì)被提升,而賦值或其他運(yùn)行邏輯會(huì)留在原地等待代碼執(zhí)行。那有個(gè)疑問(wèn)?就是變量提升了,為什么值回事undefined,而函數(shù)提升了,確實(shí)整個(gè)函數(shù)都有值。

foo()    //1
function foo(){
    console.log(1);
}
console.log(a);   //undefined
var a=1;

實(shí)際上,函數(shù)聲明和變量聲明都會(huì)被提升。但是一個(gè)值得注意的細(xì)節(jié)(這個(gè)細(xì)節(jié)可以出現(xiàn)在有多個(gè)“重復(fù)”聲明的代碼中)是函數(shù)會(huì)首先被提升,然后才是變量。這里引進(jìn)一個(gè)新的概念,執(zhí)行上下文:每次當(dāng)引擎執(zhí)行到可執(zhí)行代碼的時(shí)候,就會(huì)進(jìn)入一個(gè)創(chuàng)建一個(gè)執(zhí)行上下文。我們可以理解為,執(zhí)行上下文就是代碼的執(zhí)行環(huán)境,會(huì)形成一個(gè)作用域。

首先在這個(gè)執(zhí)行上下文的創(chuàng)建階段和代碼執(zhí)行階段

創(chuàng)建階段,會(huì)創(chuàng)建變量對(duì)象,建立作用域鏈,以及確定this的指向。

首先我們需要理解下變量對(duì)象(Variable Object)VO,可以這樣理解,變量對(duì)象就是相當(dāng)于一個(gè)容器,它會(huì)做幾件事情

1).創(chuàng)建arguments對(duì)象。搜索當(dāng)前上下文中的參數(shù),確定該對(duì)象下的屬性與屬性值。

2).檢查當(dāng)前上下文的function關(guān)鍵字聲明的函數(shù),找到之后給當(dāng)前那個(gè)函數(shù)賦予一個(gè)引用,該引用指向該函數(shù)所在內(nèi)存地址的引用,如果函數(shù)名的屬性已經(jīng)存在過(guò),那么該屬性將會(huì)被最新新的引用所覆蓋。之后繼續(xù)檢查當(dāng)前上下文中的var 變量聲明,每找到一個(gè)變量聲明,就在變量對(duì)象中給變量一個(gè)屬性,屬性值為undefined。如果存在同名屬性,為了防止同名的函數(shù)被修改為undefined,則會(huì)直接跳過(guò),原屬性值不會(huì)被修改。

這種形式也就是為什么變量聲明和函數(shù)聲明中,函數(shù)聲明會(huì)比變量聲明要提前,也就是函數(shù)優(yōu)先。

代碼執(zhí)行階段:變量對(duì)象會(huì)變成活動(dòng)對(duì)象(Active Object)AO,此時(shí)會(huì)做幾件事情:變量會(huì)進(jìn)行賦值,函數(shù)引用,執(zhí)行其他代碼

當(dāng)然,這里要注意函數(shù)參數(shù)的提升,實(shí)際上函數(shù)參數(shù)是一個(gè)隱式的提升和賦值操作。

function foo (a){
   //函數(shù)參數(shù)進(jìn)行隱式賦值    var a ;  a=2;
   console.log(a);
}
foo(2);

下面在看下代碼就知道為什么會(huì)那樣執(zhí)行了。

foo();   //在變量對(duì)象創(chuàng)建階段,也就是代碼執(zhí)行之前,foo已經(jīng)有了自己在內(nèi)存空間的函數(shù)引用了,所有函數(shù)會(huì)執(zhí)行  輸出  1
function foo(){
   console.log(1);
}
console.log(a);  //在變量對(duì)象創(chuàng)建階段,就是代碼執(zhí)行之前,變量對(duì)象找到var a;并且賦予a一個(gè)屬性值,該值為undefined;所有輸出  undefined
var a=1;
console.log(a)    //代碼執(zhí)行階段,完成變量賦值,所以會(huì)輸出 1.
foo(); // 3      //盡管重復(fù)的var 聲明會(huì)被忽略掉,但出現(xiàn)在后面的函數(shù)聲明還是可以覆蓋前面的。
function foo() {
     console.log( 1 );
}
var foo = function() {
    console.log( 2 );
};
function foo() {
    console.log( 3 );
}

當(dāng)然啦,我們只是討論提升的知識(shí),至于this之類的,后面我們?cè)賮?lái)討論。 留下幾道練習(xí)給可以試一試看掌握的程度怎么樣

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

歡迎訪問(wèn)我的個(gè)人網(wǎng)站zhengyepan
學(xué)習(xí)筆記,時(shí)間匆忙,歡迎交流,還有很多遺漏的知識(shí)點(diǎn),以后會(huì)去深入交流~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 繼承 一、混入式繼承 二、原型繼承 利用原型中的成員可以被和其相關(guān)的對(duì)象共享這一特性,可以實(shí)現(xiàn)繼承,這種實(shí)現(xiàn)繼承的...
    magic_pill閱讀 1,126評(píng)論 0 3
  • 1,javascript 基礎(chǔ)知識(shí) Array對(duì)象 Array對(duì)象屬性 Arrray對(duì)象方法 Date對(duì)象 Dat...
    Yuann閱讀 1,148評(píng)論 0 1
  • 原文:http://dmitrysoshnikov.com/ecmascript/javascript-the-c...
    jaysoul閱讀 553評(píng)論 0 0
  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,674評(píng)論 0 4
  • 二胎政策放開(kāi)之后,很多媽媽們都躍躍欲試的想湊成一個(gè)“好”字,不管最終是否達(dá)成心愿,在未來(lái)一定是非常希望兩個(gè)孩子相親...
    一佑?jì)寢?/span>閱讀 540評(píng)論 2 1

友情鏈接更多精彩內(nèi)容