js 變數 函式提公升

2021-07-04 05:15:13 字數 2273 閱讀 2076

js 變數、函式提公升

先簡單理解下作用域的概念,方便對變數與函式提公升的概念的理解

function foo() 

console.log(x);

}foo();// 2

結果為2,可見js中並沒有塊級作用域的概念

可以使用下面的方法創造自己的作用域,這樣不會干擾到外部變數

function foo() ());

}console.log(x);

}foo();// 1

結果為1,可見js中的作用域是以函式為邊界的

1.變數提公升:

變數提公升與js的預編譯有關,下面通過例子輔助說明

var a = 100;

var b = 200;

function foo()

foo();

js預編譯時會先在當前作用域中找到var宣告的變數分配空間,賦值為undefined,如果找不到就會到下一級作用域中找

上面的**的等價**如下:

var a = 100;

var b = 200;

function foo()

foo();

這樣看是不是容易理解多了。第一行var宣告了a,但是沒有賦值,因此為undefined,下面列印10、1也就順理成章了。

至於變數b,它在當前作用域中找不到,因此需要到外層作用域中找,在window下找到了變數b,可以看到它的值為200

2.函式提公升

首先要明確兩點:

<1> 只有函式宣告才會進行函式提公升

<2> 函式提公升會將函式體一起提公升上去,這點與變數提公升有所不同

下面來證明函式表示式不能進行函式提公升:

~function() ()

}()

函式前面加個~的目的是將函式宣告變成函式表示式,實際上也可以加其它運算子,比如+,-,!等,總之這個函式宣告被變成了函式表示式。

從列印結果來看第乙個alert出的是undefined,說明next根本沒有發生函式提公升。

下面來接著驗證:

a();// 123

var a = function()

a();// 321

function a()

從結果可以看出,先列印出來的反而是放在後面的a(),上面**的等價表示如下:

var a = function a()

a();

a = function()

a();

那麼如果當變數提公升與函式提公升同時發生的時候,哪個的優先順序更高呢?我們來做個實驗:

function fn()

console.log(a);

}fn();// function a(), 2

從列印順序中可以看出,函式提公升比變數提公升優先順序高,因為函式提公升是將函式體整體提公升,提公升上去後立馬賦值。等價**如下:

function fn()

console.log(a);

a = 2;

console.log(a);

}fn();

下面再來幾個有趣的例子:

b = 100;

function b()

b(); // b is not a function

//函式提公升導致的

b = 100;

var b = function()

b(); // 2

//函式表示式不存在函式提公升

function change() 

var foo = function()

var fn;

}change();

//fn提公升了,foo沒有提公升

下面還有幾個思考題:

1.

var a = 1;  

function b()

} b();// ?

console.log(a);// ?

2.

a = 10;

(function a())();

3.

function a(i) ; 

a(10);

JS函式提公升和變數提公升

js引擎在執行整個js 的過程中,分為倆步。第一步是讀取和解析js 第二部是執行。在引擎解析js 的時候,當解析器遇見變數宣告 var 變數名 和函式宣告 function 函式名 的時候,會將這些宣告提到各自作用域的最前面。在es6之前,js是沒有塊級作用域的。只有2種作用域 注 在其他語言中,被...

JS 變數提公升與函式提公升

在 es6 出來之前,沒有塊級作用域,只有全域性作用域 和 函式作用域。變數提公升指的是 將變數宣告提公升到它所在作用域的最開始部分。例子 console.log foo undefined var foo 變數提公升 console.log foo 變數提公升 相當於 var foo consol...

js函式 變數提公升 hoisting

其實我只是想複習下變數提公升的,然後看到了函式提公升,然後再看到了函式宣告 函式表示式.有必要懷著敬仰之心提及園子裡的tom大叔的解密命名函式表示式,不愧是大叔,好好地腦補了下基礎知識.在ecmascript中,建立函式的最常用的兩個方法是函式表示式和函式宣告,兩者期間的區別是有點暈,因為ecma規...