ES6基礎知識——let、const關鍵字和變數的解構賦值

小呀麼小程式設計師發表於2018-11-28

let和const關鍵字
1.let關鍵字

作用: 
   	與var類似, 用於宣告一個變數
特點:
   	在塊作用域內有效,不影響區塊外的變數
   	不能重複宣告
   	不會預處理, 不存在提升
   	使用let取代var是趨勢
應用:
   	迴圈遍歷加監聽

什麼是預處理變數提升?
js執行之前要先進行預處理(預解析),就是找var和function,找到var宣告並賦值,function提前將函式體構建好。可以在var之前呼叫變數,但是let必須在宣告後呼叫,不然會報錯。

var ali=document.getElementsByTagName('li');
   	for(var i=0;i<ali.length;i++){
   		ali[i].onclick=function(){
   		console.log(i);
   		}
   	}

上面的這段程式碼是我們在使用js時經常會遇到的問題,我們想要點選每個li對應彈出他所對應的值,但是我們發現不管我們點選哪個li最後彈出的都是最後的i值,也就是for迴圈結束後的i值。 這是因為變數ivar命令宣告的,在全域性範圍內都有效,所以全域性只有一個變數i,而迴圈內輸出的i指向的也是這個全域性的i,也就是左右陣列a的成員裡面的i指向的都是同一個i。 傳統的解決方式是使用閉包。

閉包的三個特點:兩層函式,內部函式使用外部函式的變數。內部方法在外部呼叫。

	var ali=document.getElementsByTagName('li');
   	for(var i=0;i<ali.length;i++){
   		(function(i){
   				ali[i].onclick=function(){
   					console.log(i);
   				}
   			}(i)
   	}

原理是點選事件對應的是回撥函式,回撥函式被放在事件佇列裡面,等主執行緒上的程式碼執行完,在執行回撥的函式。使用閉包也就是立即執行函式,是利用了作用域的特點。

使用let關鍵字來解決這個問題就十分簡單了。只需把var改成let就可以了

var ali=document.getElementsByTagName('li');
   	for(let i=0;i<ali.length;i++){
   		ali[i].onclick=function(){
   		console.log(i);
   		}
   	}

2.const關鍵字

作用:
   	const宣告一個只讀的常量。一旦宣告,常量的值就不能改變。const宣告的變數不得改變值,這意味著,const一旦宣告變數,就必須立即初始化,不能留到以後賦值。只宣告不賦值就會報錯。
特點:
   	只在宣告所在的塊級作用域內有效
   	在同一區塊內不能重複宣告,但是在不同區塊可以。
   	不會預處理, 不存在提升
   	不能修改。儲存不用改變的資料。
應用:
   	儲存應用需要的常量資料

本質:
const實際上保證的,並不是變數的值不得改動,而是變數指向的那個記憶體地址所儲存的資料不得改動。對於簡單型別的資料(數值、字串、布林值),值就儲存在變數指向的那個記憶體地址,因此等同於常量。但對於複合型別的資料(主要是物件和陣列),變數指向的記憶體地址,儲存的只是一個指向實際資料的指標,const只能保證這個指標是固定的(即總是指向另一個固定的地址),至於它指向的資料結構是不是可變的,就完全不能控制了。因此,將一個物件宣告為常量必須非常小心。
例如常量foo儲存的是一個地址,這個地址指向一個物件。不可變的只是這個地址,即不能把foo指向另一個地址,但物件本身是可變的,所以依然可以為其新增新屬性。

ES5 只有兩種宣告變數的方法:var命令和function命令。ES6 除了新增let和const命令,後面章節還會提到,另外兩種宣告變數的方法:import命令和class命令。所以,ES6 一共有 6 種宣告變數的方法。

二、變數的解構賦值
從陣列或物件中提取值, 對多個變數進行賦值

陣列的解構賦值
let [a,b] = [1, ‘atguigu’];

	let arr=[1,2,3,'sally',true];
	let[a,b,c,d,e]=arr; //相當於在全域性設定了5個變數a,b,c,d,e;也可以不全解構寫成[,,a,b]用逗號佔位。
	console.log(a,b,c,d,e);

對於set結構,也可以使用陣列的解構賦值

let[x,y,z]=new Set(['a','b','c']);

其實只有某種資料結構具有iterator介面,都可以採用陣列形式的解構賦值。

function* fibs() {
  let a = 0;
  let b = 1;
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

let [first, second, third, fourth, fifth, sixth] = fibs();
sixth // 5
//使用陣列解構賦值使x,y值對調
var [x,y]=[1,2];
var [x,y]=[y,x];
console.log(x,y);

解構賦值允許預設值

let [foo = true] = [];
foo // true

let [x, y = 'b'] = ['a']; // x='a', y='b'
let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'

字串的解構賦值

let [r1,r2,r3,r4,r5]="hello";
console.log(r1,r2,r3,r4,r5);

物件的解構賦值
let {n, a} = {n:‘tom’, a:12}

	let obj={username:"sally",age:19};
	//之前的寫法:let username=obj.username;
	//現在es6寫法
	let{username,age}=obj;//大括號裡必須與obj物件中的屬性重名,可以不全解構,obj是要解構的物件,相當於全域性定義的變數如上面以前的寫法。
	console.log(username,age);

物件的解構也可以指定預設值。
var {x = 3} = {}; x // 3
預設值生效的條件是,物件的屬性值嚴格等於undefined,null不等於undefined.
解構失敗變數的值等於undefined.

//給多個形參賦值
function foo({username,age}){//相當於{username,age}=obj
	console.log(username,age);
}
foo(obj);

用途
交換2個變數的值
從函式返回多個值

解構賦值的規則是,只要等號右邊的值不是物件或陣列,就先將其轉為物件。由於undefined和null無法轉為物件,所以對它們進行解構賦值,都會報錯。

相關文章