js在執行的時候,是從上到下,從左到右,一行一行執行的,但是不知道在這之前還要做一些事情,js程序在正式執行之前,會將所有var聲明的變量和function聲明的函數,預讀到所在作用域的頂部,但是對var 聲明只是將聲明提前,賦值仍然保留在原位置,function聲明,會將函數名稱和函數體都提前,而且先預聲明變量再預定義函數。這個過程也被叫做,“預解析”或者“預編譯”。
舉例:(1)
console.log(a); ? ?? //不會出錯,會輸出undefined
var a=100;
console.log(a); ? ? //100;
由于聲明提前,所以代碼會變成這樣
var a; //聲明提前
console.log(a);??? //undefined
a=100;??????????????? //賦值任然留在原位置
console.log(a);??? //100
注意1:聲明提前僅能將聲明提前到所在作用域的頂部
(2)
function? fn(){
console.log(a);??? //undefined
var? a=100;? ?
console.log(a);??? //100 ? ?? };
fn();
console.log(a);??? //? 報引用錯誤!
上面的代碼? 其實會變成這樣
function? fn(){
var? a;//僅僅提前到函數頂部
console.log(a);???? //undefined
a=100;? ?
console.log(a);??? //100??? };
fn();
console.log(a);??? //報引用錯誤
注意2:函數聲明提前不同于var 變量聲明提前,使用函數聲明語句,函數名稱和函數體均會被提前,也就是說可以在聲明一個JavaScript函數之前調用它。
舉個例子:
console.log(fn());???? //2
function? fn(){
return2;??
}
(3)
練習題1
var? a=123;
function? a(){
return1??? }
console.log(a);
解析1:這道題在弄明白什么是 “聲明提前”后比較簡單做!按照剛才講到的概念,這道題會變成這樣
var? a;
function? a() {
return? 1??? }
a=123;
console.log(a);
所以最后會輸出? 123
練習題2
function? a(){
return? 1??? };
var? a;
a();
解析2:完成這道題,還需要知道一件事情,如果未在var聲明語句中給變量指定初始值,那么雖然聲明這個變量,但在給它存入一個值之前,它的初始值就是undefined,但是多次聲明同一變量無所謂!??!所以這道題的結果是 1,代碼會預編譯為:
var? a;??? //初始值為undefined
function? a(){
??? return1??? };
a();
練習題3
function a(){
??? return? 1;? }
var? a=undefined;
a();
解析3:這道題,和第2題非常的相似,只需要明白這里 var a=undefined; 和 var a;是不同的,一個是聲明變量同時進行賦值操作,只是賦的值是undefined,一個是單純的聲明變量。代碼會預編譯為:
var? a;???? //初始值為undefined
function? a(){
return1?? };
a=undefined;
a();
所以最后的結果會報錯? a is not a function
練習題4
if( !("a"? in? window) ) {
var? a =1;??? };
var? a;
alert(a);
解析4:首先說一句,在瀏覽器中,var聲明的全局變量是屬于window對象的屬性。也就是說可以用? . 或者[ ]顯示出來(window.變量名? 或者? window[“變量名”])。
in 運算符? 是判斷對象是否為數組/對象的元素/屬性:
格式:(變量 in 對象)
注意:
當“對象”為數組時,“變量”指的是數組的“索引”;
當“對象”為對象時,“變量”指的是對象的“屬性”;
這道題也就是再說,如果 window里沒有屬性a,就聲明一個變量a,然后賦值為1,最后彈出一個警告框顯示a,當我們把這些概念弄清楚,會發現這道題其實是這樣的,
var? a;
if( !("a"? in? window) ) {
a =1;??? };
alert(a);
這樣看,我們能很清楚的看明白,在執行if語句之前,是已經聲明了變量a的,它的初始值是undefined,所以window里是有屬性a的,那么if語句執行的條件就不滿足,無法對變量a進行賦值,所以最后也會彈出undefined。