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

資訊專欄INFORMATION COLUMN

(深究)聲明提前(Hoisting)

陳偉 / 1147人閱讀

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

簡介

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

示例
函數聲明:

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

function sayHi(){

  alert("Hi")

}

通過提升其實是這樣的:

//函數聲明提升到頂部

function sayHi(){

  alert("Hi")

}

sayHi(); //不會報錯

函數表達式:

sayHi(); // 報錯  

var sayHi = function(){

  alert("Hi")

}
函數表達式其實是創建一個匿名函數然后賦值給變量,通過提升應該是這樣的:

//函數聲明和變量聲明都被提升到作用域頂部,函數優先

functionsayHi(){

  alert("Hi")

}

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

var sayHi;

sayHi(); // 報錯  

//變量賦值被留在原地

sayHi = function(){

  alert("Hi")

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

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

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

提升的機制

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

let究竟有沒有提升

MDN_let及暫存死區

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

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

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

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

為什么函數比變量提升優先級更高

未完待續...
歡迎補充批評...

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

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95715.html

相關文章

  • javascript 變量提升(Hoisting

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

    TwIStOy 評論0 收藏0
  • JavaScript-預編譯

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

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

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

    luxixing 評論0 收藏0
  • JS基礎篇--函數聲明與定義,作用域,函數聲明與表達式的區別

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

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

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

    darry 評論0 收藏0

發表評論

0條評論

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