JavaScript 中凝果,變量可以在使用后聲明祝迂,也就是變量可以先使用再聲明。
以下兩個實例將獲得相同的結(jié)果:
<script>
x = 5; // 變量 x 設(shè)置為 5
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x; // 在元素中顯示 x
var x; // 聲明 x
</script>
<script>
var x; // 聲明 x
x = 5; // 變量 x 設(shè)置為 5
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = x;
</script>
- 下面代碼條件語句if(!foo)并不會執(zhí)行器净,為什么foo會被賦值為10:
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();
- alert輸出了1:
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
C語言的一個例子:
#include <stdio.h>
int main() {
int x = 1;
printf("%d, ", x); // 1
if (1) {
int x = 2;
printf("%d, ", x); // 2
}
printf("%d\n", x); // 1
}
程序依次輸出了1型雳,2,1; 因為在C語言中山害,我們有塊級作用域(block-level scope)纠俭。在一個代碼塊的中變量并不會覆蓋掉代碼塊外面的變量。
JavaScript的一個例子:
var x = 1;
console.log(x); // 1
if (true) {
var x = 2;
console.log(x); // 2
}
console.log(x); // 2
輸出的結(jié)果為1粗恢,2柑晒,2 if代碼塊中的變量覆蓋了全局變量。
那是因為JavaScript是一種函數(shù)級作用域(function-level scope)所以if中并沒有獨立維護一個scope,變量x影響到了全局變量x
- JavaScript實現(xiàn)一種類似塊級作用域的效果, 閉包:
function foo() {
var x = 1;
if (x) {
(function () {
var x = 2;
// some other code
}());
}
// x is still 1.
alert(x);
}
foo();
Hoisting in Javascript
在代碼運行前眷射,函數(shù)聲明和變量定義通常會被解釋器移動到其所在作用域的最頂部
- 1
function foo() {
bar();
var x = 1;
}
被代碼解釋器編譯完后匙赞,將變成下面的形式:
function foo() {
var x;
bar();
x = 1;
}
- 2
function foo() {
if (false) {
var x = 1;
}
return;
var y = 1;
}
function foo() {
var x, y;
if (false) {
x = 1;
}
return;
y = 1;
}
變量的上升(Hoisting)只是其定義上升,而變量的賦值并不會上升妖碉。
創(chuàng)建一個函數(shù)的方法有兩種涌庭,一種是通過函數(shù)聲明function foo(){}
另一種是通過定義一個變量var foo = function(){}
這兩種在代碼執(zhí)行上的區(qū)別:
function test() {
foo(); // TypeError "foo is not a function"
bar(); // "this will run!"
var foo = function () { // function expression assigned to local variable 'foo'
alert("this won't run!");
}
function bar() { // function declaration, given the name 'bar'
alert("this will run!");
}
}
test();
foo()調(diào)用的時候報錯了,而bar能夠正常調(diào)用
var foo首先會上升到函數(shù)體頂部欧宜,然而此時的foo為undefined,所以執(zhí)行報錯坐榆。而對于函數(shù)bar, 函數(shù)本身也是一種變量,所以也存在變量上升的現(xiàn)象冗茸,但是它是上升了整個函數(shù)席镀,所以bar()才能夠順利執(zhí)行匹中。
開頭的兩段代碼:
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();
實際為:
var foo = 1;
function bar() {
var foo;
if (!foo) {
foo = 10;
}
alert(foo);
}
bar();
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a);
實際為:
var a = 1;
function b() {
function a() {}
a = 10;
return;
}
b();
alert(a);
改變了function a的值,從函數(shù)變?yōu)閿?shù)值10豪诲,其實函數(shù)本身也可看做變量的定義顶捷,function 和 var 返回的類型不同而已。