先看以下**:
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 ...