前言
是不是經(jīng)常遇到面試問你句狼,為什么會變量提升,函數(shù)提升,它的行為又是什么满俗?
解答
js程序編譯有兩個步驟:
- 預(yù)解析 (就是執(zhí)行上下文转捕,有三類變量聲明,函數(shù)聲明和this唆垃,本文暫不討論this五芝,后續(xù)專門寫)
- 代碼執(zhí)行
demo
var a = 1;
function a() {}
a = 2;
如上述demo中,其實真正解析成:
var a; // 第一步
a = function () {} // 第二步
a = 1; // 第三步
a = 2; // 第四步
第一步辕万,變量聲明提升a枢步;第二步,函數(shù)提升渐尿,把函數(shù)賦值給a醉途;第三步變量賦值a=1;第四步變量賦值a=2砖茸。
:編譯器對代碼進行預(yù)解析隘擎,先將變量聲明提升,再將函數(shù)提升凉夯,接下來就是引擎進行變量賦值货葬。(記住,變量提升只是聲明提升劲够,賦值不提升震桶,函數(shù)提升將提升到賦值之前。)
隱式變量分配權(quán)重大
demo
function parent(a) {
var b = 2;
function a() {return 'a'}
function b() {return 'b'}
b = 3;
return a + b;
}
console.log(parent(1)); // function a() {return 'a'} 3
大家看到這個答案是不是很疑惑征绎,不應(yīng)該函數(shù)先提升尼夺,賦值后運行嗎?為何return a +b 得到的是函數(shù)a + 3呢炒瘸?
解析上述demo:
function parent() {
var a;
var b;
a = 1;
a = function() {return "a";};
b = function() {return "b";};
b = 2;
b = 3;
return a + b;
}
console.log(parent()); // function a() {return 'a'}3
隱式變量分配在函數(shù)提升之前,所謂隱式變量分配在這里就是函數(shù)傳遞過來的值1寝衫。
:編譯器對代碼進行預(yù)解析顷扩,先將變量聲明提升,隱式變量分配提升(函數(shù)傳值)慰毅,再將函數(shù)聲明提升隘截,接下來就是js引擎讓代碼逐步執(zhí)行。
給大家出兩道題:
一汹胃、為何第一個num是undefined
var num = 123;
function foo1(){
console.log( num ); //undefined
var num = 456;
console.log( num ); //456
}
foo1();
提示:foo1函數(shù)提升了婶芭。
二、為何打印1
foo(); // 1
var foo;
function foo() { console.log( 1 );
}
foo = function() { console.log( 2 );
}
需要注意的是着饥,遇到匿名函數(shù)(函數(shù)表達式)當成普通變量來處理犀农,不要當成函數(shù)聲明。
更多內(nèi)容可以看我的集錄: 全面攻陷js:更新中...