ECMAScript與JavaScript的關(guān)系
ECMAScript是JavaScript語言的國際標準,JavaScript是ECMAScript的實現(xiàn)。
let 與 const 的用法
let 用來聲明變量,所聲明的變量只在let命令所在的 代碼塊 內(nèi)有效。
const 用來聲明常量,所謂常量就是物理指針不可以更改的變量。
1、代碼塊與塊級作用域
{
let a = 1;
}
console.log(a) // 報錯 a is not defined
- 只需要用
{}包起來,這個{}和其中代碼生成一個代碼塊; - 在塊中,
let和const聲明的變量和常量對外都是不可見的,稱之為塊級作用域; - 只有使用
let和const聲明的變量或者常量在塊中對外不可見,var聲明的變量對外依然可見; - 可以認為是let和const創(chuàng)建了塊級作用域。
塊級作用域特性
(1)ES6 允許塊級作用域的任意嵌套
{{{{{let insane = 'Hello World'}}}}};
(2)外層作用域無法讀取內(nèi)層作用域的變量
{{{{
{let insane = 'Hello World'}
console.log(insane); // 報錯
}}}};
(3)內(nèi)層作用域可以定義外層作用域的同名變量
{{{{
let insane = 'Hello World';
{let insane = 'Hello World'}
}}}};
2、let指令
- (1)let聲明的變量只在變量聲明時所在的代碼塊內(nèi)有效。
{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
- (2)不存在變量提升現(xiàn)象
var命令會發(fā)生”變量提升“現(xiàn)象,即變量可以在聲明之前使用,值為undefined;但let所聲明的變量一定要在聲明后使用,否則報錯。
// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;
// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;
- (3)暫時性死區(qū)
在代碼塊內(nèi),使用let命令聲明變量之前,該變量都是不可用的。這在語法上,稱為“暫時性死區(qū)”(TDZ)。
if (true) {
// TDZ開始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結(jié)束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
暫時性死區(qū)的本質(zhì)就是,只要一進入當前作用域,所要使用的變量就已經(jīng)存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量。
- (4)
let不允許在同一作用域重復(fù)聲明變量
// 報錯
function func() {
let a = 10;
var a = 1;
}
// 報錯
function func() {
let a = 10;
let a = 1;
}
同時,也不能在函數(shù)內(nèi)部重新聲明參數(shù)
function func(arg) {
let arg; // 報錯
}
function func(arg) {
{
let arg; // 不報錯
}
}
- (5)關(guān)于
for循環(huán)
for循環(huán)的計數(shù)器,很合適使用let命令,在for 循環(huán)中使用let定義變量,只在for的循環(huán)周期內(nèi)可以使用,在循環(huán)體外引用就會報錯
for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
for循環(huán)設(shè)置循環(huán)變量的那部分是一個父作用域,而循環(huán)體內(nèi)部是一個單獨的子作用域
for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
3、const指令
- (1)
const聲明一個只讀的常量。一旦聲明,常量的值就不能改變。
const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
- (2)
const一旦聲明變量,就必須立即初始化,只聲明不賦值,就會報錯。
const foo;
// SyntaxError: Missing initializer in const declaration
- (3)
const的作用域與let命令相同:只在聲明所在的塊級作用域內(nèi)有效。
if (true) {
const MAX = 5;
}
MAX // Uncaught ReferenceError: MAX is not defined
- (4)
const命令聲明的常量也是不提升,同樣存在暫時性死區(qū),只能在聲明的位置后面使用。
if (true) {
console.log(MAX); // ReferenceError
const MAX = 5;
}
- (5)
const聲明的常量,也與let一樣在同一作用域中不可重復(fù)聲明。
var message = "Hello!";
let age = 25;
// 以下兩行都會報錯
const message = "Goodbye!";
const age = 30;
- (6)
const實際上保證的,并不是變量的值不得改動,而是變量指向的那個內(nèi)存地址不得改動。- 對于簡單類型的數(shù)據(jù)(數(shù)值、字符串、布爾值),值就保存在變量指向的那個內(nèi)存地址,因此等同于常量。
- 對于復(fù)合類型的數(shù)據(jù)(主要是對象和數(shù)組),變量指向的內(nèi)存地址,保存的只是一個指向?qū)嶋H數(shù)據(jù)的指針,
const只能保證這個指針是固定的(即總是指向另一個固定的地址),至于它指向的數(shù)據(jù)結(jié)構(gòu)是不是可變的,就完全不能控制了。
const foo = {};
// 為 foo 添加一個屬性,可以成功
foo.prop = 123;
foo.prop // 123
// 將 foo 指向另一個對象,就會報錯
foo = {}; // TypeError: "foo" is read-only
上面代碼中,常量foo儲存的是一個地址,這個地址指向一個對象。不可變的只是這個地址,即不能把foo指向另一個地址,但對象本身是可變的,所以依然可以為其添加新屬性。
4、ES6 聲明變量的六種方法
varfunctionletconstimportclass