- 引擎會 在解釋 JavaScript 代碼以前首先對其進行編譯。
- 編譯階段中的一部分工做就是找到全部的 聲明,並用合適的做用域將它們關聯起來。也正是詞法做用域 的核心內容。
- ReferenceError 同做用域判別失敗相關,而 TypeError 則表明做用域判別成功了,可是對 結果的操做是非法或不合理的。
var a = 2
提高的是var a
;而不會提高賦值操做a=2
,賦值操做將原地保留;
所以,正確的思考思路是bash
var a;
a =2;
複製代碼
a = 2;
var a;
console.log( a );//輸出2
複製代碼
由於:函數
var a;
a = 2;
console.log( a ); // 2
複製代碼
console.log( a );
var a = 2; //輸出undefined
複製代碼
由於spa
var a;
console.log( a );
a = 2;
複製代碼
foo();
function foo() {
console.log( a ); // undefined
var a = 2;
}
複製代碼
foo 函數的聲明(這個例子還包括實際函數的隱含值)被提高了,所以第一行中的調用能夠正常執行。 foo 是函數聲明,函數聲明會被提高,可是函數表達式卻不會被提高。看下面例子4;code
foo(); // TypeError
bar(); // ReferenceError
var foo = function bar() { // ...
};
複製代碼
由於ip
因此上面代碼等同於:作用域
var foo;
foo(); // TypeError
bar(); // ReferenceError
foo = function() {
var bar = ...self...
// ...
}
複製代碼
後面的函數聲明 > 函數聲明 > 變量聲明it
foo(); // 1
var foo;
function foo() {
console.log( 1 );
}
foo = function() {
console.log( 2 );
};
複製代碼
會輸出 1 而不是 2 ! 等同於io
function foo() {
console.log( 1 );
}
foo(); // 1
foo = function() {
console.log( 2 );
};
複製代碼
要注意避免重複聲明,特別是當普通的 var 聲明和函數聲明混合在一塊兒的時候,不然會引 起不少危險的問題!console