本文一共 600 字,讀完只需 3 分鐘javascript
JS 中,咱們會理所固然地認爲代碼是一句一句地執行的,但並不徹底正確。java
singer = "周杰倫";
var singer;
console.log(singer); // 周杰倫
sing(); // 故事的小黃花
function sing() {
console.log("故事的小黃花");
}
複製代碼
以上第一段代碼,若是按照正常流程,後面的 var singer
會從新把值默認聲明爲 undefined
,但結果倒是 '周杰倫';閉包
以上第二段代碼,會理解成,先執行,後聲明,就會報錯,但結果卻沒有。app
以上代碼塊實際上是能夠改寫成這樣的:函數
var singer = undefined;
singer = "周杰倫";
console.log(singer); // 周杰倫
function sing() {
console.log("故事的小黃花");
}
sing(); // 故事的小黃花
複製代碼
這是由於:post
JS 定義聲明會在編譯階段進行,賦值和其餘操做則是在執行階段進行。ui
因此,先有聲明,再有賦值和執行,這就是變量和函數的聲明提高。this
var foo = "bar";
function foo() {
}
typeOf(foo); // string
var foo = "bar";
function foo() {
}
typeOf(foo); // string
複製代碼
不管函數聲明放在變量聲明前,仍是後,變量聲明都覆蓋了函數聲明。spa
如下代碼會輸出 10,是爲何呢?code
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();
複製代碼
由於:
每一個域都會進行聲明提高。
上面代碼至關於:
var foo = 1;
function bar() {
var foo = undefined;
if (!foo) { // !foo === true
var foo = 10;
}
alert(foo);
}
bar();
複製代碼
首先,什麼是函數表達式?
// 函數聲明
function foo() {
console.log("函數聲明");
}
// 函數表達式
var foo = function() {
console.log("函數表達式");
}
複製代碼
函數表達式,不會聲明提高,因此:
foo(); // Uncaught TypeError: foo is not a function
// 函數表達式
var foo = function() {
console.log("函數表達式");
}
複製代碼
JavaScript 中存在一種聲明提高的機制,有變量聲明和函數聲明。JS 引擎會在編譯階段查找每一個做用域的聲明,而賦值和運算則在執行時進行。
函數定義分爲函數聲明和函數表達式,其中,函數聲明有聲明提高,函數表達式則沒有。
歡迎關注個人我的公衆號「謝南波」,專一分享原創文章。