JavaScript中的聲明提前

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。

轉載自談談 JavaScript 中的 聲明提前(hoisting) - CSDN博客

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容