国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

(深究)聲明提前(Hoisting)

陳偉 / 1153人閱讀

摘要:有意思的是,這意味著變量在聲明之前甚至已經(jīng)可用。的這個特性被非正式地稱為聲明提前,即函數(shù)里聲明的所有變量但不涉及賦值都被提前至函數(shù)體的頂部。但實際上會將其看成兩個聲明和。第二個賦值聲明會被留在原地等待執(zhí)行階段。

簡介

JavaScript的函數(shù)作用域是指在函數(shù)內(nèi)聲明的所有變量在函數(shù)體內(nèi)始終是可見的。有意思
的是,這意味著變量在聲明之前甚至已經(jīng)可用。JavaScript的這個特性被非正式地稱為
聲明提前(hoisting) ,即JavaScript函數(shù)里聲明的所有變量(但不涉及賦值)都被“提
前”至函數(shù)體的頂部。如果對提升不太明白的,請參考JavaScript高級程序設(shè)計177頁函數(shù)表達式.MDN變量提升

示例
函數(shù)聲明:

sayHi(); //不會報錯,在執(zhí)行代碼之前會先讀取函數(shù)聲明,也就是 函數(shù)聲明提升

function sayHi(){

  alert("Hi")

}

通過提升其實是這樣的:

//函數(shù)聲明提升到頂部

function sayHi(){

  alert("Hi")

}

sayHi(); //不會報錯

函數(shù)表達式:

sayHi(); // 報錯  

var sayHi = function(){

  alert("Hi")

}
函數(shù)表達式其實是創(chuàng)建一個匿名函數(shù)然后賦值給變量,通過提升應(yīng)該是這樣的:

//函數(shù)聲明和變量聲明都被提升到作用域頂部,函數(shù)優(yōu)先

functionsayHi(){

  alert("Hi")

}

//變量聲明被提升到頂部

var sayHi;

sayHi(); // 報錯  

//變量賦值被留在原地

sayHi = function(){

  alert("Hi")

}
函數(shù)提升優(yōu)先級高于變量提升
a()  // alert(1)
var a = 1
function a(){
  alert(1)
}

通過提升:
function a(){
  alert(1)
}
var a 
a()
a = 1
提問 為什么會有提升

比起那些編譯過程只有三個步驟的語言的編譯器,JavaScript引擎要復(fù)雜得多。例如,在語法分析 和代碼生成階段有特定的步驟來對運行性能進行優(yōu)化,包括對冗余元素進行優(yōu)化等。我們通過編譯器在詞法階段進行詞法分析,生成詞法作用域,詞法作用域就是用來管理引擎如何在當(dāng)前作用域以及嵌套 的子作用域中根據(jù)標(biāo)識符名稱進行變量查找。提升的作用使得所有聲明都在詞法作用域的上方,這樣引擎在作用域及嵌套作用域中變量查找可以更快更簡單。

提升的機制

引擎會在解釋 JavaScript代碼之前首先對其進行編譯。編譯階段中的一部分工作就是找到所有的聲明,并用合適 的作用域?qū)⑺鼈冴P(guān)聯(lián)起來,這也正是詞法作用域的核心內(nèi)容。
因此,正確的思考思路是,包括變量和函數(shù)在內(nèi)的所有聲明都會在任何代碼被執(zhí)行前首先被處理。
當(dāng)你看到 var a = 2; 時,可能會認(rèn)為這是一個聲明。但JavaScript實際上會將其看成兩個聲 明: var a; 和 a = 2; 。第一個定義聲明是在編譯階段進行的。第二個賦值聲明會被留在原地等待執(zhí) 行階段。

let究竟有沒有提升

MDN_let及暫存死區(qū)

var i = 10;
function a(){
   i = 3;
   var i = 1;  //因為 var 提升了 所以在 function里 創(chuàng)建了 局部變量 i
}
console.log(i) // 10
let a = 1
{
  a = 2;
  let a  = 3;   //報錯
}

//這里的報錯,我認(rèn)為是規(guī)范化強制性報錯,并不代表let沒有提升
//我的猜想如下,

let a = 1
{
  let a // 暫存死區(qū) 開始的地方就是這里
  a = 2 // 由于 a = 2 在 暫存死區(qū) 中,所以報錯
  a // 暫存死區(qū) 結(jié)束的地方就是這里
}
為什么let要強制性報錯

不推薦使用eval及with等,使用let/const 代替var,使用塊級作用域
目的就是為了,減少詞法欺騙以及作用域的混亂導(dǎo)致的性能問題,使得javascript引擎運行更快。
使用let 就要按照let 的使用規(guī)定,不然和使用var又沒什么區(qū)別了,這是我的想法。

為什么函數(shù)比變量提升優(yōu)先級更高

未完待續(xù)...
歡迎補充批評...

參考文章:
知乎提問
strack overflow
JavaScript引擎解析預(yù)編譯
我的博客園
《你不知道的JavaScript 上》

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/95715.html

相關(guān)文章

  • javascript 變量提升(Hoisting

    摘要:簡介變量提升意味著變量和函數(shù)的聲明會在物理層面移動到代碼的最前面,但這么說并不準(zhǔn)確。實際上變量和函數(shù)聲明在代碼里的位置是不會動的,而是在編譯階段被放入內(nèi)存中。 簡介 變量提升意味著變量和函數(shù)的聲明會在物理層面移動到代碼的最前面,但這么說并不準(zhǔn)確。 實際上變量和函數(shù)聲明在代碼里的位置是不會動的,而是在編譯階段被放入內(nèi)存中。 聲明變量的方法 var、let、const 不用以上關(guān)鍵字...

    TwIStOy 評論0 收藏0
  • JavaScript-預(yù)編譯

    摘要:預(yù)編譯發(fā)生在函數(shù)執(zhí)行前也就是說函數(shù)執(zhí)行時,預(yù)編譯已經(jīng)結(jié)束。五總結(jié)理解預(yù)編譯需要明白變量函數(shù)聲明和變量賦值。預(yù)編譯階段,只進行變量函數(shù)聲明,不會進行變量的初始化即變量賦值,所有變量的值都是變量賦值是在解釋執(zhí)行階段才進行的。 一、JS的概念 JavaScript ( JS ) 是一種具有函數(shù)優(yōu)先的輕量級解釋型或即時編譯型的編程語言。 二、JS語言特點 2.1 單線程 (1)JavaScri...

    Aldous 評論0 收藏0
  • 理解 JavaScript(二)

    摘要:所以形式參數(shù)是本地的,不是外部的或者全局的。這叫做函數(shù)聲明,函數(shù)聲明會連通命名和函數(shù)體一起被提升至作用域頂部。這叫做函數(shù)表達式,函數(shù)表達式只有命名會被提升,定義的函數(shù)體則不會。 Scoping & Hoisting var a = 1; function foo() { if (!a) { var a = 2; } alert(a); }; ...

    luxixing 評論0 收藏0
  • JS基礎(chǔ)篇--函數(shù)聲明與定義,作用域,函數(shù)聲明與表達式的區(qū)別

    摘要:在中,有四種方式可以讓命名進入到作用域中按優(yōu)先級語言定義的命名比如或者,它們在所有作用域內(nèi)都有效且優(yōu)先級最高,所以在任何地方你都不能把變量命名為之類的,這樣是沒有意義的形式參數(shù)函數(shù)定義時聲明的形式參數(shù)會作為變量被至該函數(shù)的作用域內(nèi)。 Scoping & Hoisting 例: var a = 1; function foo() { if (!a) { var ...

    TerryCai 評論0 收藏0
  • JS 作用域鏈

    摘要:首先,在創(chuàng)建函數(shù)時,作用域鏈內(nèi)就會先填入對象,圖片只例舉了全部變量中的一部分。然后,解釋器進入函數(shù)的執(zhí)行環(huán)境,同樣的,首先填入父級的作用域鏈,就是的,包括了對象活動對象。之后再把的活動對象填入到作用域鏈最頂部,這就是的作用域鏈了。 之前學(xué)習(xí)JS函數(shù)部分時,提到了作用域這一節(jié),但是因為使用材料書不同,今天在讀博客的時候發(fā)現(xiàn)其實還有一個知識點即作用域鏈,所以來寫一些個人理解和認(rèn)識加深記憶。...

    darry 評論0 收藏0

發(fā)表評論

0條評論

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