一、變量聲明
JavaScript有三種聲明:
- var 聲明一個(gè)變量
- let 聲明一個(gè)塊作用域的局部變量(block scope local variable)
- const 聲明一個(gè)只讀的常量。
1. 變量求值
- 用
var或let聲明的且未賦初值的變量,值會(huì)被設(shè)定為undefined。 - 試圖訪問(wèn)一個(gè)未聲明的變量或者訪問(wèn)一個(gè)使用
let聲明的但未初始化的變量會(huì)導(dǎo)致一個(gè)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 值會(huì)被轉(zhuǎn)換為 NaN。
var a;
a + 2; // Evaluates to NaN
- 當(dāng)你對(duì)一個(gè)
null變量求值時(shí),空值null在數(shù)值類型環(huán)境中會(huì)被當(dāng)作0來(lái)對(duì)待
var n = null;
console.log(n * 32); // Will log 0 to the console
2. 變量的作用域
- 在所有函數(shù)之外聲明的變量,叫做全局變量,因?yàn)樗杀划?dāng)前文檔中的任何其他代碼所訪問(wèn)。
- 在函數(shù)內(nèi)部聲明的變量,叫做局部變量,因?yàn)樗荒茉谠摵瘮?shù)內(nèi)部訪問(wèn)。
- 語(yǔ)句塊作用域
ECMAScript 6 之前的JavaScript沒(méi)有 語(yǔ)句塊作用域;相反,語(yǔ)句塊中聲明的變量將成為語(yǔ)句塊所在代碼段的局部變量。例如,如下的代碼將在控制臺(tái)輸出 5,因?yàn)?x 的作用域是聲明了 x 的那個(gè)函數(shù)(或全局范圍),而不是 if 語(yǔ)句塊。
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 變量的另一特別之處是,你可以引用稍后聲明的變量而不會(huì)引發(fā)異常,然而提升后的變量將返回 undefined 值。
1).
console.log(x === undefined); // true
var x = 3;
等價(jià)于
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';
})();
等價(jià)于
// will return a value of undefined
var myvar = 'my value';
(function() {
var myvar;
console.log(myvar); // undefined
myvar = 'local value';
})();
- 在 ECMAScript 2015 中,
let(const)將不會(huì)提升變量到代碼塊的頂部。因此,在變量聲明之前引用這個(gè)變量,將拋出錯(cuò)誤ReferenceError。
console.log(x); // ReferenceError
let x = 3;
二、函數(shù)提升
對(duì)于函數(shù),只有函數(shù)聲明會(huì)被提升到頂部,而不包括函數(shù)表達(dá)式(表達(dá)式定義的函數(shù),稱為匿名函數(shù),匿名函數(shù)沒(méi)有函數(shù)提升)。
- 函數(shù)聲明
foo(); // "bar"
function foo() {
console.log('bar');
}
- 函數(shù)表達(dá)式
baz(); // TypeError: baz is not a function
var baz = function() {
console.log('bar2');
};
【注】:此時(shí)的 baz 相當(dāng)于一個(gè)聲明的變量,類型為 undefined 。由于 baz 只是相當(dāng)于一個(gè)變量,因此瀏覽器認(rèn)為 baz() 不是一個(gè)函數(shù)。