變數的作用域在函數之外聲明的變數,叫做全局變數,因為它可被當前文檔中的任何其他代碼所訪問。在函數內部聲明的變數,叫做局部變數,因為它只能在當前函數的內部訪問。 ECMAScript 6 之前的 JavaScript 沒有 語句塊作用域;相反,語句塊中聲明的變數將成為語句塊所在函數(或全局作用域)的局 ...
變數的作用域
在函數之外聲明的變數,叫做全局變數,因為它可被當前文檔中的任何其他代碼所訪問。在函數內部聲明的變數,叫做局部變數,因為它只能在當前函數的內部訪問。
ECMAScript 6 之前的 JavaScript 沒有 語句塊作用域;相反,語句塊中聲明的變數將成為語句塊所在函數(或全局作用域)的局部變數。例如,如下的代碼將在控制台輸出 5,因為 x 的作用域是聲明瞭 x 的那個函數(或全局範圍),而不是 if 語句塊。
if (true) {
var x = 5;
}
console.log(x); // 5
如果使用 ECMAScript 6 中的 let 聲明,上述行為將發生變化。
if (true) {
let y = 5;
}
console.log(y); // ReferenceError: y 沒有被聲明
變數提升
JavaScript 變數的另一個不同尋常的地方是,你可以先使用變數稍後再聲明變數而不會引發異常。這一概念稱為變數提升;JavaScript 變數感覺上是被“提升”或移到了函數或語句的最前面。但是,提升後的變數將返回 undefined 值。因此在使用或引用某個變數之後進行聲明和初始化操作,這個被提升的變數仍將返回 undefined 值。
/**
* 例子1
*/
console.log(x === undefined); // true
var x = 3;
/**
* 例子2
*/
// will return a value of undefined
var myvar = "my value";
(function() {
console.log(myvar); // undefined
var myvar = "local value";
})();
上面的例子,也可寫作:
/**
* 例子1
*/
var x;
console.log(x === undefined); // true
x = 3;
/**
* 例子2
*/
var myvar = "my value";
(function() {
var myvar;
console.log(myvar); // undefined
myvar = "local value";
})();
由於存在變數提升,一個函數中所有的var語句應儘可能地放在接近函數頂部的地方。這個習慣將大大提升代碼的清晰度。
在 ECMAScript 6 中,let(const)將不會提升變數到代碼塊的頂部。因此,在變數聲明之前引用這個變數,將拋出引用錯誤(ReferenceError)。這個變數將從代碼塊一開始的時候就處在一個“暫時性死區”,直到這個變數被聲明為止。
console.log(x); // ReferenceError
let x = 3;
函數提升
對於函數來說,只有函數聲明會被提升到頂部,而函數表達式不會被提升。
/* 函數聲明 */
foo(); // "bar"
function foo() {
console.log("bar");
}
/* 函數表達式 */
baz(); // 類型錯誤:baz 不是一個函數
var baz = function() {
console.log("bar2");
};
本文引自:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types#Unicode.E7.BC.96.E7.A0.81