1、js作用域
在es5中,js只有兩種形式的作用域:全域性作用域和函式作用域,在es6中,新增了乙個塊級作用域(最近的大括號涵蓋的範圍),但是僅限於let方式申明的變數。
2、變數宣告
1var x; //
變數宣告
2var x=1; //
變數宣告並賦值
3 x = 1; //
定義全域性變數並賦值
3、函式宣告
function fn(){}; //函式宣告並定義
var fn = function(){}; //
實際上是定義了乙個區域性變數fn和乙個匿名函式,然後把這個匿名函式賦值給了fn
4、變數提公升
var tmp = newdate();
function
fn()
fn();
a情形
var tmp = newdate();
function
fn()
}fn();
b情形
var tmp = newdate();
function
fn()
}fn();
c情形從上面可以看到,b情形和c情形為什麼不同於a情形,就是因為變數提公升了(ps: c情形不同於b情形的是判斷條件為true,但是這裡不是看**有沒有被執行,是看變數有沒有被定義)。fn函式裡面定義了同名變數tmp,無論在函式的任何位置定義tmp變數,它都將被提公升到函式的最頂部。等同於下面情形:
var tmp = newdate();
console.log(tmp);
function
fn()
}fn();
這裡需要說明的是,雖然所有的申明(包括es5的var、function,和es6的function *、let、const、class)都會被提公升,但是var、function、function *和let、const、class的的提公升卻並不相同!具體原因可以看這裡的說明(大體的意思是雖然let,const,class也被提公升了,但是卻並不會被初始化,這時候去訪問他們則會報referenceerror異常,他們需要到語句執行的時候才會被初始化,而在被初始化之前的狀態叫做temporal dead zone)。
因為這樣的原因,推薦的做法是在申明變數的時候,將所用的變數都寫在作用域(全域性作用域或函式作用域)的最頂上,這樣**看起來就會更清晰,更容易看出來那個變數是來自函式作用域的,哪個又是來自作用域鏈。
5、重複宣告
var x = 1;console.log(x);
if(true
)console.log(x);
上面的輸出其實是:1 2 2。雖然看起來裡面x申明了兩次,但上面說了,js的var變數只有全域性作用域和函式作用域兩種,且申明會被提公升,因此實際上x只會在最頂上開始的地方申明一次,var x=2的申明會被忽略,僅用於賦值。也就是說上面的**實際上跟下面是一致的:
var x = 1;console.log(x);
if(true
)console.log(x);
6、函式和變數同時提公升的問題
console.log(fn);function
fn(){};
var fn = 'string';
上面的輸出結果其實是:function fn(){}
,也就是函式內容。
console.log(fn);var fn = function
fn(){};
var fn = 'string';
這時輸出結果就是undefined,知道上面的宣告提公升的道理就不難理解了。
總結:要徹底理解js的作用域和hoisting,只要記住以下三點即可:
1、所有申明都會被提公升到作用域的最頂上
2、同乙個變數申明只進行一次,並且因此其他申明都會被忽略
3、函式宣告的優先順序優於變數申明,且函式宣告會連帶定義一起被提公升
注意:
通過with語句,可以臨時改變執行期上下文的作用域鏈,此時的對非var定義的變數進行訪問,會首先訪問with中物件的屬性,然後才會向上順著作用域鏈向上檢查該屬性。
js的變數作用域 ,變數提公升
function 結果 undefined 10 等同於下面 var a undefined 定義全域性變數 function 分析 1.在產生乙個作用域的時候,會預編譯一次裡面的變數,其中的動作是將所有的變數名,函式名,提前定義,然後在賦予當前的變數的所在作用域,執行。2.變數名的定義會覆蓋函式名...
變數提公升 作用域
console.log a undefined console.log window.a undefined console.log a in window true 在變數提公升階段,在全域性作用域中宣告了乙個變數a,此時就已經把a當做屬性賦值給window了,只不過此時還沒有給a賦值,預設值un...
作用域與變數提公升
js中變數的作用域有全域性作用域和區域性作用域兩種,作用域簡單來講就是變數與函式的可訪問範圍。宣告提前是在js預編譯是就進行了,變數提公升知識提公升變數的宣告,並不會吧值也提上來。例1 var name one function test var name one function test 解析 ...