一单旁、變量聲明
JavaScript有三種聲明:
- var 聲明一個變量
- let 聲明一個塊作用域的局部變量(block scope local variable)
- const 聲明一個只讀的常量。
1. 變量求值
- 用
var
或let
聲明的且未賦初值的變量,值會被設(shè)定為undefined
。 - 試圖訪問一個未聲明的變量或者訪問一個使用
let
聲明的但未初始化的變量會導(dǎo)致一個ReferenceError
異常被拋出。
var a;
console.log('The value of a is ' + a); // The value of a is undefined
console.log('The value of b is ' + b); // The value of b is undefined
var b;
console.log('The value of c is ' + c); // Uncaught ReferenceError: c is not defined
let x;
console.log('The value of x is ' + x); // The value of x is undefined
console.log('The value of y is ' + y); // Uncaught ReferenceError: y is not defined
let y;
- 數(shù)值類型環(huán)境中 undefined 值會被轉(zhuǎn)換為 NaN。
var a;
a + 2; // Evaluates to NaN
- 當(dāng)你對一個
null
變量求值時,空值null
在數(shù)值類型環(huán)境中會被當(dāng)作0
來對待
var n = null;
console.log(n * 32); // Will log 0 to the console
2. 變量的作用域
- 在所有函數(shù)之外聲明的變量奢米,叫做全局變量,因為它可被當(dāng)前文檔中的任何其他代碼所訪問纠永。
- 在函數(shù)內(nèi)部聲明的變量鬓长,叫做局部變量,因為它只能在該函數(shù)內(nèi)部訪問尝江。
- 語句塊作用域
ECMAScript 6 之前的JavaScript沒有 語句塊作用域涉波;相反,語句塊中聲明的變量將成為語句塊所在代碼段的局部變量炭序。例如啤覆,如下的代碼將在控制臺輸出 5,因為 x 的作用域是聲明了 x 的那個函數(shù)(或全局范圍)惭聂,而不是 if 語句塊窗声。
if (true) {
var x = 5;
}
console.log(x); // x is 5
如果使用 ECMAScript 6 中的 let 聲明,上述行為將發(fā)生變化辜纲。
if (true) {
let y = 5;
}
console.log(y); // ReferenceError: y is not defined
3. 變量聲明提升
變量聲明提升(variable hoisting)笨觅,JavaScript 變量的另一特別之處是,你可以引用稍后聲明的變量而不會引發(fā)異常耕腾,然而提升后的變量將返回 undefined 值见剩。
1).
console.log(x === undefined); // true
var x = 3;
等價于
var x;
console.log(x === undefined); // true
x = 3;
2).
// will return a value of undefined
var myvar = 'my value';
(function() {
console.log(myvar); // undefined
var myvar = 'local value';
})();
等價于
// will return a value of undefined
var myvar = 'my value';
(function() {
var myvar;
console.log(myvar); // undefined
myvar = 'local value';
})();
- 在 ECMAScript 2015 中,
let
(const
)將不會提升變量到代碼塊的頂部扫俺。因此苍苞,在變量聲明之前引用這個變量,將拋出錯誤ReferenceError
狼纬。
console.log(x); // ReferenceError
let x = 3;
二羹呵、函數(shù)提升
對于函數(shù)骂际,只有函數(shù)聲明會被提升到頂部,而不包括函數(shù)表達式(表達式定義的函數(shù)担巩,稱為匿名函數(shù)方援,匿名函數(shù)沒有函數(shù)提升)。
- 函數(shù)聲明
foo(); // "bar"
function foo() {
console.log('bar');
}
- 函數(shù)表達式
baz(); // TypeError: baz is not a function
var baz = function() {
console.log('bar2');
};
【注】:此時的 baz
相當(dāng)于一個聲明的變量涛癌,類型為 undefined
。由于 baz
只是相當(dāng)于一個變量送火,因此瀏覽器認(rèn)為 baz()
不是一個函數(shù)拳话。