ES6學習筆記()
看網上一些ES6相關資料,來學習ES6,記錄下其間學習的筆記,以及一些疑惑,供後期自己方便查閱,未解決疑問以後懂了再加上……
ES6學習筆記(一)相關內容:作用域、let命令、const命令
一、作用域的概念
ES6之前,有 全域性作用域 和 函式作用域 到了ES6,新增加了一個————塊作用域
關於塊作用域,可以看成一個{}包住的區域,就是一個塊作用域。
在塊作用域中用let定義的變數,只能在塊作用域中有效,而塊作用域之外的無效,可以理解為它的生命週期已經結束了
function test() { for(let i = 1; i < 3; i ++) { console.log(i); //==> 1,2 } console.log(i); //報錯 }
如看上面定義的函式,for迴圈的{},就是一個塊作用域,在它的塊作用域之外的地方訪問,就會報錯
二、let命令
第一點:let 與 var 的區別?
//let
function test() {
for(let a = 1; a < 3; a ++) {
console.log(a); //==> 1,2
}
console.log(a); //報錯
}
test();
解釋: let宣告的變數只在自己的塊作用域裡有效
//var function test() { for(var a = 1; a < 3; a ++) { console.log(a); //==> 1,2 } console.log(a); //==> 3 } test();
疑惑一:下面兩端程式碼為什麼輸出那個值
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[1]();
上面程式碼中,變數i是var命令宣告的,在全域性範圍內都有效,所以全域性只有一個變數i。每一次迴圈,變數i的值都會發生改變,而迴圈內被賦給陣列a的函式內部的console.log(i),裡面的i指向的就是全域性的i。也就是說,所有陣列a的成員裡面的i,指向的都是同一個i,導致執行時輸出的是最後一輪的i的值,也就是 10。
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[1]();
上面程式碼中,變數i是let宣告的,當前的i只在本輪迴圈有效,所以每一次迴圈的i其實都是一個新的變數,所以最後輸出的是6。
上面解釋是網上的解釋,看的似懂非懂,先留個心
第二點:關於嚴格模式 其中一點:變數未宣告,不能引用,否則就會報引用錯誤(ReferenceError)
function test() {
console.log(i); //報錯:引用錯誤(ReferenceError)
}
test();
在ES5中要使用嚴格模式,要在程式碼最前面加一行程式碼: “use strict”; //啟動這個檔案採用嚴格模式 而ES6中不需要加這一行程式碼,它是預設強制開啟了嚴格模式的
所以,上面函式報錯提示的是 ReferenceError(引用錯誤),而不是i是undefined
其中第二點:使用let,不能重複定義變數,即,不允許在相同作用域內,重複宣告同一個變數
function func() {
let a = 10;
var a = 1; //命令列報錯
}
function func() {
let a = 10;
let a = 1; //命令列報錯
}
第三點:不存在變數提升 變數提升:變數可以在宣告之前使用,值為undefined。 var命令會發生“變數提升”現象,但是let命令不存在
// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;
// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;
變數foo用var命令宣告,會發生變數提升,即指令碼開始執行時,變數foo已經存在了,但是沒有值,所以會輸出undefined。 變數bar用let命令宣告,不會發生變數提升。這表示在宣告它之前,變數bar是不存在的,這時如果用到它,就會丟擲一個錯誤。
第四點:暫時性死區(網上的解釋,) ES6 明確規定,如果區塊中存在let和const命令,這個區塊對這些命令宣告的變數,從一開始就形成了封閉作用域。凡是在宣告之前就使用這些變數,就會報錯。
{
t = 'abc';
console.log(t); // ReferenceError
// let t;
}
疑惑:上面加上 ‘let t;’ 這一條程式碼能打印出 abc,但是網上說的是‘在宣告之前就使用變數,就會報錯’,而這裡 在宣告之前確實就使用變量了啊,為什麼沒有報錯
總之,在程式碼塊內,使用let命令宣告變數之前,該變數都是不可用的。這在語法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)。
if (true) {
// TDZ開始
tmp = 'abc';
console.log(tmp); // ReferenceError //這裡我電腦上能打印出 abc ,不知道啥原因
let tmp; // TDZ結束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
三、 const命令
第一點:使用const,定義的是常量,只讀,不能改 let、var 與 const 的區別?
//let和var 一樣,這裡有let
function test() {
let a = 1;
a = 2;
console.log(a);// ==>2
}
test();
//const
function test() {
const PI = 3.1415926;
//PI = 8; //加上這行,會報錯:"PI" is read-only
console.log(PI);//不加"PI = 8"這行,控制檯輸出3.1415926
}
test();
第二點:const命令也有塊作用域的概念
function test() {
let a = 1;
if (a) {
const PI = 3.1415926;
}
console.log(PI);//報錯:Uncaught ReferenceError: PI is not defined
}
test();
第三點:const宣告的時候必須賦值
function test() {
const PI;
PI = 3.1415926;
console.log(PI);//報錯:提示宣告不完整
}
test();
第四點:使用const定義常量,如果值是數值,則不允許修改,如第一點, 但是,如果值等於一個物件,這裡的物件裡的值 是可以修改的,看下面兩段程式碼
function test() {
const a = {
b: 2
}
console.log(a); //控制檯能打印出物件 {b: 2}
}
test();
function test() {
const a = {
b: 2
}
a.c = 3;
console.log(a);//控制檯能打印出物件 {b: 2, c: 3}
}
test();
其實,“const定義的變數,是一個常量,不允許修改,只能讀” 這句話並沒有錯,是正確的。第四點和第一點並不衝突。 那麼,為什麼上面值等於一個物件卻可以修改呢?
解釋:物件是引用型別,它返回的是儲存物件的那個指標,即,上面的a,其實就是 指向 儲存它等於的那個物件 的指標,這個指標是不會變的,但是可以讀,而這個物件本身卻是可以改變的
第五點:cost也和let一樣不能重複宣告 程式碼:略