1、變量提升
什麼是變量提升?
在函數體內聲明的變量,無論你是在函數的最底端還是中間聲明的,那麼都會把該變量的聲明提升到函數的最頂端(相當於第一行),但是隻是提升變量的聲明,不會賦值。
var num = 10;
fun(); //輸出結果爲undefined
function fun(){
console.log(num);
var num = 20;
}
/*上面這個函數相當於:
function fun(){
var num;
console.log(num);
num = 20;
}
*/
2、函數提升
什麼是函數提升?
在JavaScript中以函數聲明的方式創建的函數
就跟用var創建的變量一樣,它們的聲明都會提前聲明,這就使得我們在JavaScript中可以調用函數在前面,而聲明函數在後面
,這就是函數提升。
func();
function func(){
alert(“函數執行了!”);
}
/*
上面這段代碼相當於:
function func(){
alert(“函數執行了!”);
}
func();
*/
3、函數與變量同名時的變量提升
alert(fun); // 最終輸出結果爲:輸出fun函數體
function fun(){
alert(“我是一個函數”);
}
var fun = “我是一個變量”;
alert(fun); // 輸出:我是一個變量
/* 爲什麼第一個alert輸出的是fun函數體,而第二個alert輸出的是“我是一個變量”?
因爲用var聲明的變量及function聲明的函數在執行前都會將聲明提升到最前面,如果變量與函數同名,
那麼在聲明的時候會忽略變量,只提升函數聲明! */
/*
上面這段代碼相當於:
function fun(){
alert(“我是一個函數”);
}
alert(fun);
fun = “我是一個變量”;
alert(fun);
*/
4、變量搜索原則(變量訪問原則)
在JavaScript中變量的訪問(搜索)是有原則的:
1)、首先在訪問變量的作用域(函數)中查找該變量,如果找到直接使用
2)、如果沒有找到,去上一級作用域中查找,如果找到直接使用
3)、如果還是沒有找到,則再去上一級作用域中查找,知道全局作用域
4)、如果找到了就直接使用,如果沒有找到則報錯
var num = 123;
function foo1(){
function foo2(){
console.log(num);
}
/*當調用foo2時,會首先去foo2這個作用域中查找是否有num變量,結果沒找到則去上一級作用域(即foo1)中查找是否有foo1變量,
結果還 是沒找到,則再去上一級作用域(全局作用域)中查找,結果找到了,則拿來使用*/
foo2();
}
5、變量提升、變量搜索機制經典面試題
fun();
console.log(b);
console.log(c);
console.log(a);
functoin fun(){
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}