javascript 函數宣告提升,函數體是否會一起被提升?
如果不是,有以下反例:
console.log(demo.toString()); //‘function demo() {console.log('ok')}’
demo(); //‘ok’
function demo() {
console.log('ok')
}
如果是,有以下反例:
console.log(func) // undefined ,如果直接执行func()函数抛出TypeError异常
if(true){
function func() {
console.log('11');
};
}else{
function func() {
console.log('22');
};
}
func(); // 11
第一個例子說明函數體同樣是被提升了的,如果按照這個思路來理解第二段程式碼,「重命名」函數會互相覆蓋,後面的會覆蓋前面的,所以,console.log( func)會輸出'function func() {console.log('22');};' 這個字串,但是實際上並非如此。
因此產生了三個疑問:
請問要如何理解「變數提升,函數優先」呢?
函數體是不是同樣提升?
第二段程式碼的運行結果如何解釋?
習慣沉默2017-05-19 10:45:15
if代表條件判斷,編譯的時候應該是不會去執行程式碼,只會檢查語法詞法分析。你可以嘗試換瀏覽器,或是啟用嚴格模式做測試,有可能會有意想不到的事情發生哦~
1.變數提升,函數優先,就是 var a = 1;function fun(){};中var a;和function fun(){}會提升上去,提升到作用域的頂層。
2.同樣提升了。函數表達式不會,因為他是 var fun = function(){};這種,只會提升var fun;
3.第二段,其實可以用下面的方法解釋
var func;
console.log(func)
if(true){
func=function func() {
console.log('11');
};
}else{
func=function func() {
console.log('22');
};
}
func(); // 11
某草草2017-05-19 10:45:15
在非嚴格模式下,放在if語句內部的函數宣告是否會提昇在各個核心的實作都不同。
結論是,函數會提升,但在if語句內部時要看各個核心的實作。
嚴格模式禁止了不在腳本或函數層面上的函數宣告
PHP中文网2017-05-19 10:45:15
函數和變數宣告會被提升,函數提升優先於變數提升,要直接運行的程式碼不能被提升吧。第一個代碼裡直接都提升了。第二個程式碼你定義的函數是在if 語句結構裡面,兩個log 和if 在運行堆疊裡面應該是依序執行,顯然if 語句運行之前你的func是還沒宣告的 。
怪我咯2017-05-19 10:45:15
es6 有一些區塊級作用域的規則,這個地方 如果你用舊版的 node或低版的chrome 運行
相當於以下程式碼
function func() {
console.log('22');
};
console.log(func);
if(true){
}else{
}
func(); // 22
可是 高版的 node和chrome限制了 這樣的變數的提升,就出現了 你程式碼的狀況! ~! ~
仅有的幸福2017-05-19 10:45:15
因為JavaScript是一種函數級作用域(function-level scope
)
所以if中并没有独立维护一个scope
英文解釋:
javascript-variable-scope-and-hoisting-explained
中文解釋:Javascript作用域與變數提升
PHP中文网2017-05-19 10:45:15
一般不建議在條件判斷語句中書寫函數宣告。
這在ECMAScript中屬於無效語法,javascript引擎會嘗試修正錯誤,將其轉換為正常合理的狀態。然後這種修正的做法在不同的瀏覽器是不一樣的。建議用函數表達式:
var func;
if(true){
func=function {
console.log('11');
};
}else{
func=function {
console.log('22');
};
}