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規...