1. 程式人生 > >ES6學習筆記()

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一樣不能重複宣告 程式碼:略