變數宣告提公升 Vs 函式宣告提公升

2021-07-07 10:44:45 字數 3604 閱讀 9017

先看以下**:

1)var in_window = "a" in window; console.log(in_window); 

2)var in_window = "a" in window; console.log(in_window); if(!("a" in window))

3)var a; var in_window = "a" in window; console.log(in_window); if(!("a" in window))

輸出的結果分別是:false true true。如何解釋? 這是由於在js的變數作用域中有個規則:所有變數宣告都在範圍作用域的頂部!也就是說,在2)**中,if語句塊內的申明的變數a,會自動提到上面去申明。其等價於3)。

由上述的分析可知,可以理解下面**的輸出結果是undefined。

if(!("a" in window))  console.log(a); //undefined
該**其實相當於:

var a; if(!("a" in window"))  console.log(a);
再試一次:

var s = '';

if (false)

瀏覽器中的除錯結果如下:

有圖有真相。變數a的宣告的確提公升了。

鞏固題: 

var s = ''; while(false)  console.log(a); //undefined

if(!("a" in window)) console.log(a); //1

console.log(a); //報錯,"referenceerror: a is not defined."

定義函式有兩種方式:一種是函式申明,另一種是函式表示式。

函式申明形式:

function functionname(arg0, arg1, arg2)
函式表示式形式:

var functionname = function(arg0, arg1, arg2)
關於函式申明,它有乙個重要特徵就是

函式宣告提公升

,看下面的例子。

sayhi();

function sayhi()

瀏覽器中的除錯結果如下: 發現函式sayhi已經被宣告了,並且其值為sayhi函式。第一行**執行後,輸出hi。

若採用函式表式的形式,此時我們能看到變數宣告提公升的效果。

sayhi();

var sayhi = function()

在瀏覽中的除錯效果如下:發現變數sayhi提公升了,它的值是undefined,第一行**執行的話,會報錯:"typeerror:undefined is not a function"。

接下來的例子就很好理解。

if(!("a" in window))  } console.log(a); //undefined該**等價於:
var a; if(!("a" in window)) } console.log(a); 其實無論if語句塊中的a被定義成何種型別的值,a的申明都提前了。(變數提公升)
將上述**變形如下:

if(!("a" in window)) } console.log(a); //function a() (函式申明提公升)
由此可以總結出,所有函式宣告也在範圍作用域的頂部。那麼函式宣告和變數宣告,哪個的優先順序高呢?

如下圖對比所示:函式宣告會覆蓋變數宣告。

但是如果在變數宣告的同時,對變數進行初始化,情況會有所不同。對同乙個變數名,宣告變數同時初始化變數優先順序高於函式宣告

再練幾題:

function a() 

var s = '';

if(a())

console.log(a);

上述**輸出的a值為:function a()

function a()

var s = '';

if(a())

console.log(a);

上述**輸出的a值為:1

function a()

var a;

var s = '';

if(a())

console.log(a);

上述**輸出的a值為:1

由對上述**的分析:可以總結出如下規律:

1)變數宣告提公升變數申明在進入執行上下文就完成了。

只要變數在**中進行了宣告,無論它在哪個位置上進行宣告, js引擎都會將它的宣告放在範圍作用域的頂部;

2)函式宣告提公升執行**之前會先讀取函式宣告,意味著可以把函式申明放在呼叫它的語句後面。

上進行宣告, js引擎都會將它的宣告放在範圍作用域的頂部;

3)變數or函式宣告函式宣告會覆蓋變數宣告,但不會覆蓋變數賦值。

同乙個名稱標識a,即有變數宣告var a,又有函式宣告function a() {},不管二者宣告的順序,函式宣告會覆蓋變數宣告,也就是說,此時a的值是宣告的函式function a() {}。注意:如果在變數宣告的同時初始化a,或是之後對a進行賦值,此時a的值變數的值。

eg: var a; var c = 1; a = 1; function a()  console.log(a); //1
原文參考:變數宣告提公升 vs. 函式宣告提公升

JS變數宣告和函式宣告提公升

很多時候,在直覺上,我們都會認為js 在執行時都是自上而下一行一行執行的,但是實際上,有一種情況會導致這個假設是錯誤的。a 2 var a console.log a 按照傳統眼光,console.log a 輸出的應該是undefined,因為var a在a 2之後。但是,輸出的是2。再看第二段 ...

函式的變數宣告提公升

變數存在的範圍就是變數的作用域。全域性作用域 變數在程式中一直存在,所有地方都可以讀取。區域性作用域 變數只在函式內部存在 函式外部宣告變數就是全域性變數 函式內部定義的變數外部無法讀取,顧稱 區域性變數 使用規則 函式允許訪問函式外的變數 整個 結構中只有函式可以限定作用域 作用域規則首先使用提公...

JS變數宣告提公升

js的變數作用域是離它最近的封閉語塊或 塊,包含他們內部的函式.在 塊中宣告會被隱式的提公升到封閉函式的頂部 1 function 6 var y 1 7 上面的 會被js解釋成下面的格式 1 function 8 有時候我們會不小心的在函式內部重新宣告了已有的變數 function text x ...