JavaScrip變量聲明關(guān)鍵字var、let、const詳解
JavaScript 中的變量是松散類型的,可以保存任何類型數(shù)據(jù),變量只不過是一個名稱。JavaScript 中,可以聲明變量的關(guān)鍵字有var、let和const。
一、var
使用var定義變量,可以保存任何類型的值。若不初始化變量,變量會保存undefined。
1.1函數(shù)級作用域
使用var定義的變量會成為包含它的函數(shù)的局部變量。
function func() {
var a = 'hi'; // 局部變量
}
func();
console.log(a); // ReferenceError: a is not defined
變量a在函數(shù)內(nèi)部使用var定義,調(diào)用函數(shù)func,會創(chuàng)建這個變量并給它賦值。函數(shù)執(zhí)行結(jié)束后,變量就會被銷毀,所以上述代碼最后一行會報錯,顯示變量a未定義。
若在函數(shù)內(nèi)部,不使用var操作符,直接給變量a賦值,那么a就成為了全局變量,可以在函數(shù)外部訪問到。在瀏覽器環(huán)境下,a成為window對象的屬性。
function func() {
a = 'hi'; // 全局
}
func();
console.log(a); // hi
console.log(window.a); // hi
console.log(window.a === a); // true
1.2 變量提升
使用var聲明變量,會自動提升到函數(shù)作用域頂部,如下代碼:
function func() {
console.log(a);
var a = 1;
}
func(); // undefined
代碼沒有報錯,輸出了undefined,這是因為變量的聲明被提升到了函數(shù)作用域頂部,等價于如下代碼:
function func() {
var a;
console.log(a);
a = 1;
}
func(); // undefined
1.3 重復(fù)聲明
另外,使用var重復(fù)聲明同一個變量也可以:
function func() {
var a = 1;
var a = 2;
var a = 3;
console.log(a);
}
func(); // 3
1.4 全局變量掛載到 window
瀏覽器環(huán)境中,全局作用域下,使用var聲明的變量,會掛載到window對象上。
var a = 1; console.log(window.a === a); // true
一道面試題:
console.log("1":a,b);
var a = 12,b="34";
function foo(){
console.log("2":a,b);
var a=b=12;
console.log("3":a,b);
}
foo()
console.log("4":a,b);
答案:
1 : undefined,undefined //變量已經(jīng)聲明但是未賦值,這里為什么會說變量已經(jīng)聲明了,是因為js編譯時會把所有的變量聲明到最前面,其次是函數(shù)的聲明
2: undefined, ‘34’ //因為下面的var a=又把a聲明了一次所以,a就又是undefined,注意這里b并沒有被聲明,如果把var a=b=12改成,var a=12,b=12那么答案就是undefined,undefined
3: 12,12 //a,b均已聲明并賦值
4: 12,12 //a,b均已聲明并賦值,但是這里要和上一個區(qū)分,b=12是因為在函數(shù)中重新賦值了。就如第二條所說,如果把var a=b=12改成,var a=12,b=12那么答案就是12,“34”并且這個12是第二行賦值的。
二、let
let也可以聲明變量,但和var操作符有很大的區(qū)別。
2.1 塊級作用域
以下代碼會報錯,因為let聲明的作用域,具有塊級作用域,即被{}包裹的部分。
if (true) {
let a = 10;
}
console.log(a); // a is not defined
2.2 不可重復(fù)聲明
以下代碼,執(zhí)行到let a = 2就會報錯,因為變量a在當(dāng)前塊級作用域中已經(jīng)被聲明過了,不能重復(fù)聲明。
if (true) {
let a = 1;
let a = 2; // SyntaxError: Identifier 'a' has already been declared
let a = 3;
}
另外,如果混用var和let聲明變量,也是不允許的,下面的代碼都會報錯:
let a; var a; // 報錯
var a; let a; // 報錯
2.3 不存在變量提升(暫時性鎖區(qū))
使用let聲明的變量,不能在聲明之前訪問它。
if (true) {
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 1;
}
實際上,JavaScript 也會注意出現(xiàn)在塊后面的let聲明,只不過在此之前不能以任何方式來引用未聲明的變量。在let聲明之前的執(zhí)行瞬間被稱為暫時性死區(qū)。
2.4 全局變量不會掛載到 window
和var不同,即使在全局作用域下,使用let聲明的變量也不會掛載到window對象。
var a = 1; let b = 2; console.log(window.a === a); // true console.log(window.b === b); // false
2.5 不依賴條件聲明
if (typeof name === 'undefined') {
let name;
}
// name 被限制在 if {} 塊的作用域內(nèi)
name = 'Matt'; // 全局賦值
try {
console.log(age); // 如果 age 沒有聲明過,則會報錯
} catch (error) {
let age;
}
// age 被限制在 catch {}塊的作用域內(nèi)
age = 26; // 全局賦值
三、 const
const的特點與let基本一致,但const有一些自己的特點。
3.1 聲明變量時必須同時初始化
以下聲明報錯,因為聲明的同時沒有初始化變量。
const a; // Missing initializer in const declaration
3.2 不能修改聲明后的變量
使用const定義了一個變量后,不能再更改它的值:
const a = 1; a = 2; // TypeError: Assignment to constant variable
這里有一個誤區(qū),實際上,使用const聲明的變量,不能修改的是內(nèi)存地址!!
具體規(guī)則如下:
- 當(dāng)const定義的常量為基本數(shù)據(jù)類型時,不能被修改。
- 當(dāng)const定義的常量為引用數(shù)據(jù)類型時,可以通過其屬性進行數(shù)據(jù)修改。
基本數(shù)據(jù)類型的值就保存在內(nèi)存地址中,所以const定義的基礎(chǔ)數(shù)據(jù)類型不可被改變。 而引用數(shù)據(jù)類型指向的內(nèi)存地址只是一個指針,通過指針來指向?qū)嶋H數(shù)據(jù),也就是說,不可被改變的是指針,而不是數(shù)據(jù),所以const定義的引用數(shù)據(jù)類型的常量可以通過屬性來修改其數(shù)據(jù)。
例如,使用const定義了一個數(shù)組,雖然不能更改數(shù)據(jù)類型,但可以通過push等方法,修改這個數(shù)組中的數(shù)據(jù)。
const arr = []; arr.push(1, 2, 3); console.log(arr); // [ 1, 2, 3 ]
四、總結(jié)及最佳實踐
| var | let | const |
|---|---|---|
| 函數(shù)級作用域 | 塊級作用域 | 塊級作用域 |
| 重復(fù)聲明 | 不可重復(fù)聲明 | 不可重復(fù)聲明 |
| 變量提升 | 不存在變量提升 | 不存在變量提升 |
| 值可更改 | 值可更改 | 值不可更改 |
| 全局變量掛載到window | 全局變量不會掛載到window | 全局變量不會掛載到window |
通常,寫 JavaScript 代碼時,遵循以下原則:
- 不使用var
- const優(yōu)先,let次之
一道面試題:
for (var i = 1; i <= 5; i++) {
setTimeout(function () {
console.log(i);
}, 0);
}
答案:6 6 6 6 6
到此這篇關(guān)于JavaScrip變量聲明關(guān)鍵字var、let、const的文章就介紹到這了,更多相關(guān)JS變量聲明關(guān)鍵字var、let、const內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript前端和后臺進行數(shù)據(jù)交互方法示例
這篇文章主要介紹了javascript前端和后臺進行數(shù)據(jù)交互方法示例,文章通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Object.defineProperty()函數(shù)之屬性描述對象
這篇文章主要介紹了Object.defineProperty()函數(shù)之屬性描述對象,JavaScript?提供了一個內(nèi)部數(shù)據(jù)結(jié)構(gòu),用來描述對象的屬性,控制它的行為,比如該屬性是否可寫、可遍歷等等。這個內(nèi)部數(shù)據(jù)結(jié)構(gòu)稱為:屬性描述對象2022-09-09
通過JavaScript腳本復(fù)制網(wǎng)頁上的一個表格
通過JavaScript腳本復(fù)制網(wǎng)頁上的一個表格...2006-07-07
微信小程序獲取用戶信息的兩種方法wx.getUserInfo與open-data實例分析
這篇文章主要介紹了微信小程序獲取用戶信息的兩種方法wx.getUserInfo與open-data,結(jié)合實例形式分析了wx.getUserInfo與open-data獲取用戶信息的相關(guān)操作技巧與使用注意事項,需要的朋友可以參考下2019-05-05
js實現(xiàn)鼠標(biāo)點擊左上角滑動菜單效果代碼
這篇文章主要介紹了js實現(xiàn)鼠標(biāo)點擊左上角滑動菜單效果代碼,涉及JavaScript基于鼠標(biāo)事件動態(tài)變換頁面元素樣式的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-09-09

