let
1.使用let所聲明的對象只在命令所在的代碼塊內有效
//所謂代碼塊 簡單的說就是在花括號裏面
{
let a = 1;
var v = 2;
}
console.log(a);// a is not defined
console.log(b);//2
//注意:花括號裏的let聲明的變量不能被外面獲取但是var可以
//類似於es5中我們常說的閉包
!function(){
var b = 1;
}();
console.log(b);
我們在代碼塊之外呢 是拿不到代碼塊內所聲明的變量的
2.使用let聲明的變量在預解析中是不能被解析的
es5中 聲明之前是可以訪問到變量a的,因爲在瀏覽器的預解析過程中,尋找var 定義的變量和 function ,然後將這些變量保存在作用域中,值都是undefined;然後再往下逐步執行代碼…(這裏不做過多解釋,想了解的自行google)
console.log(a);//undefined
var a = 1;
console.log(b);//報錯 b 沒有被定義
let b = 2;
暫時性死區
let b = 1;
function fn(){
b = 2; //暫時性死區
let b = 3;
}
3.不允許重複聲明
在同一個作用域下不允許再次聲明已經聲明過的變量。
var a = 1;
let a = 2;
let b =1;
let b =2;
4.for循環中
還記得當年for循環中的坑麼,也同時是大多數面試中的考點。
//假設我頁面上有5個按鈕 btn
for(var i=0,len=btn.length;i<len;i++){
btn[i].onclick = function(){
console.log(i);
}
}
//你就會驚訝的發現不管點擊哪個按鈕都會打印出5;
//當然 解決辦法也很簡單 要麼就是給btn添加一個自定義屬性
for(var i=0,len=btn.length;i<len;i++){
btn[i].index = i;
btn[i].onclick = function(){
console.log(this.index);
}
}
//要麼就是閉包的方式
//將每次for循環的i傳入到閉包函數中
for(var i=0,len=btn.length;i<len;i++){
(function(i){
btn[i].onclick = function(){
console.log(i);
}
})(i);
}
//但是呢,我們有了let之後就不用那麼麻煩了,只需要簡單的把var改成let就可以了
還有個需要注意的地方
for(let i=0;i<5;i++){ //有兩作用域,循環語句中是父作用域,循環體中是子作用域 let i =10; console.log(i); } console.log(i);//報錯了
const
const 和 let 很相似 同樣在命令所在的代碼塊內有效,常量不會被提升,同時不能被重複聲明。
不同的是:
1.聲明時必須賦值.
2.1.使用const 聲明常量是基本數據類型的時候,值不能被改變
2.2.如果聲明的是引用數據類型(對象),則引用不能被改變,但是對象裏的數據可以改變
const a = 1;
a = 2 ;//報錯;
const obj = {};
obj.a = 1;//是可以的