一.提升
1.js代碼的執(zhí)行分為兩個步驟
a.
預(yù)解析
提升(hoisting
)
JavaScript
代碼在預(yù)解析階段,會對以
var
聲明的變量名,和
function
開頭的語句塊,進行提升操作
b.
執(zhí)行
func();
function
func(){
alert("Funciton has been called");
}
2.如何提升
a.
變量的提升
alert(
a);
var a = 1;
提升之后的代碼模擬
var a;
alert(
a);
a = 1;
b.
函數(shù)同名,如何提升
預(yù)處理的時候,會將兩個函數(shù)全部提升,但是后面的函數(shù)會覆蓋掉前面函數(shù)
func1(); //last
function
func1(){
console.log('This is first func1');
}
func1(); //last
function
func1(){
console.log('This is last func1');
}
//
預(yù)解析提升后的代碼
function
func1(){
console.log('This is first func1');
}
function
func1(){
console.log('This is last func1');
}
func1(); //last
func1(); //last
c.
變量和函數(shù)同名
在提升的時候,如果有變量和函數(shù)同名,會忽略掉變量,只提升函數(shù)
alert(foo); //undefined
函數(shù)體
function
foo(){}
var foo = 2;
alert(foo); //2
//
預(yù)解析 提升后的代碼
function
foo(){};
alert(foo);
foo=2;
alert(foo);
3.變量提升是分作用域的
var num = 456;
function test(){
console.log(num);
var num = 10;
}
test();//
提升代碼之后
var num;
num = 456;
function test(){
var num; //
定義未賦值
console.log(num);
num = 10;
}
test(); // undefined
var num = 456;
function
f1() {
console.log(num);
num = 10;
}
f1();
console.log(num);
//
提升之后的代碼
var num;
function
f1(){
console.log(num);
num = 10;
}
num = 456;
f1(); //456
console.log(num); //10
當(dāng)調(diào)用
f1
()時,定義了一個新的全局變量,
num=10
;
4.函數(shù)表達式與函數(shù)聲明提升
a.
函數(shù)聲明全部被提前
;
b.
函數(shù)表達式(變量聲明)僅將變量提前,賦值操作沒有被提前
;
foo(); //
函數(shù)聲明
foo_later(); // foo_later is not a function
function
foo(){ console.log('
函數(shù)聲明
'); }
var foo_later =
function(){ console.log('
函數(shù)表達式
'); }
提升之后的代碼
function
foo(){ console.log('
函數(shù)聲明
'); } //
函數(shù)聲明全部被提前
var foo_later; //
函數(shù)表達式(變量聲明)僅將變量提前,賦值操作沒有被提前
foo();
foo_later();
foo_later =
function(){ console.log('
函數(shù)表達式
'); }
5.變量搜索原則
a.
在使用變量的時候
首先在所在的作用域中查找;
如果找到了
就直接使用;
如果沒有找到
就去上級作用域中查找。
b.
重復(fù)以上步驟
如果直到0
級作用域鏈也就是全局作用域還沒有找到,報錯。
var num = 456;
function
f() {
num = 678;
function
foo() {
var num = 999;
console.log(num); // 999
}
foo();
console.log(num); //
}
f();
提升之后的代碼
var num;
function
f(){
function
foo() {
var num;
num = 999;
console.log(num); // 999
}
num = 678;
foo();
console.log(num); //678
}
num = 456;
f();
來源:簡書