- 通過var定義的變量,作用域是整個(gè)封閉函數(shù),是全域的 。通過let定義的變量,作用域是在塊級(jí)或是子塊中。
for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
//計(jì)數(shù)器i只在for循環(huán)體內(nèi)有效,在循環(huán)體外引用就會(huì)報(bào)錯(cuò)。1234567
-
變量提升現(xiàn)象:瀏覽器在運(yùn)行代碼之前會(huì)進(jìn)行預(yù)解析,首先解析函數(shù)聲明,定義變量,解析完之后再對(duì)函數(shù)、變量進(jìn)行運(yùn)行、賦值等。
-不論var聲明的變量處于當(dāng)前作用域的第幾行,都會(huì)提升到作用域的頭部。
-var 聲明的變量會(huì)被提升到作用域的頂部并初始化為undefined,而let聲明的變量在作用域的頂部未被初始化
// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;
//相當(dāng)于
var foo; //聲明且初始化為undefined
console.log(foo);
foo=2;
12345678
// let 的情況
console.log(bar); // 報(bào)錯(cuò)ReferenceError
let bar = 2;
//相當(dāng)于在第一行先聲明bar但沒有初始化,直到賦值時(shí)才初始化
123456
- 但是直接用let聲明變量不賦值是會(huì)打印undefined,還是初始化了,只是let聲明放在賦值之后,let聲明會(huì)提前但不會(huì)初始化。
let a;
alert(a);//值為undefined
alert b;//會(huì)報(bào)錯(cuò)
let b;12345
- 只要塊級(jí)作用域內(nèi)存在let命令,它所聲明的變量就“綁定”這個(gè)區(qū)域,不再受外部的影響。總之,在代碼塊內(nèi),使用let命令聲明變量之前,該變量都是不可用的,盡管代碼塊外也存在相同全局變量。
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
alert(tmp); //輸出值為123,全局tmp與局部tmp不影響1234567
- let不允許在相同作用域內(nèi),重復(fù)聲明同一個(gè)變量。
// 報(bào)錯(cuò)
function () {
let a = 10;
var a = 1;
}
// 報(bào)錯(cuò)
function () {
let a = 10;
let a = 1;
}
[轉(zhuǎn)自]:https://blog.csdn.net/zuiziyoudexiao/article/details/76890102s