ES6 新增了兩個聲明兩個聲明標識符的方式: let 和 const。
- let 用來聲明變量,並且會在當前作用域形成 代碼塊
- conts 用來聲明常量,所謂常量就是物理指針不可以更改的變量。
其實我個人是沒有其他語言基礎的,第一次看到這兩個定義,瞬間懵逼有沒有。代碼塊是什么鬼? 物理指針還能勉強理解。
- 所謂代碼塊,大可不必感覺它有多么高深。在JS中你想形成代碼塊最簡單的做法就是 :
{
let a = 1;
}
console.log(a) // 報錯 a is not defined
也就是說 你只需要用 {} 包起來,這個 {} 就是一個代碼塊。
let
好,接下來介紹下 let 的特性,使用 let 聲明的變量,只能在當前代碼塊中訪問和使用,有些類似於函數作用域,但是它又有幾點不同的地方。
- let 聲明變量,變量不會被提升。
function fn1(){
console.log(a);
let a = 1;
}
fn1(); // 報錯
var b = 2;
function fn2(){
console.log(b);
let b = 1;
}
fn2(); // 報錯
- for 循環中 使用let 定義變量,只在for的循環周期內可以使用。
// 在ES5 中如果想使用for循環每次的i需要使用閉包的特性
var arr = [];
for(var i=0; i<5; i++){
arr.push(function(){
console.log(i);
})
}
arr[1]() // 5
arr[2]() // 5
arr[3]() // 5
arr[4]() // 5
/*
為什么每次都是5,因為for循環每次做的事只是向數組中存入一個函數,這個函數的功能是 打印 i,但是函數並沒有立刻執行。而這個i是通過var i 這句話來聲明的。當for循環跑完,咱們都知道此時 i 的值是5。所以當你去執行函數的時候,自然打印出5.
*/
如果想使用每次循環中的i的值 可以利用ES5的閉包:
var arr = [];
for(var i=0; i<5; i++){
arr.push((function (a){
return function (){
console.log(a);
}
})(i))
}
arr[1]() // 1
arr[2]() // 2
arr[3]() // 3
// 以上寫法等價於下面這種寫法,注意參數i和形參i,此i非彼i
/*
for(var i=0; i<5; i++){
(function (i){
arr.push(function (){
console.log(i)
})
})(i)
}
*/
如果使用ES6提供的let來聲明變量,那么就會變得so easy
var arr = []; // let arr = [] 都可以
for(let i=0; i<5; i++){
arr.push(function (){
console.log(i)
})
}
arr[0]() // 0
arr[1]() // 1
arr[2]() // 2
一些朋友可能會覺得特別不適應。為什么這樣就能彈出 0, 1, 2?其實需要注意個問題,就是這個let i = 0; 聲明的位置,是在 for的() 內,那么你可以理解成,在 for 的內部 就定義了一個 i 而且是使用 let 定義的。所以每次循環就相當於在當前循環的i值的前提下向數組push的。
所以大家在使用的時候需要注意以下幾個問題:
let i;
for(i = 0; i < 5; i++){
setTimeout(function(){
console.log(i); // 5 5 5 5 5
},1000)
}
不同於:
for(let i = 0; i < 5; i++){
setTimeout(function(){
console.log(i); // 0 1 2 3 4
},1000)
}
const
const 除了不能改變物理指針的特性,其他特性和 let 一樣。
當聲明普通數據類型的時候,那么一但聲明了,就不可以再改變。
const a = 1;
a = 2; //Uncaught TypeError: Assignment to constant variable.
當聲明復雜數據類型的時候,物理指針不可以改變,但是可以改變數據內的屬性值,以及可以給數據添加新屬性等操作。
const o = {a: 1};
o.a = 2;
o.b = 3;
console.log(o);
o = {}; // 報錯
最后還有一個值得注意的問題:在ES6中不存在函數提升,算是修復了ES5得一個bug
看個例子:
// ES5
function a(){
console.log(1);
}
function fn(){
a();
if(false){
function a(){
console.log(2)
}
}
}
fn(); // 無理由報錯 找不到a,個人認為很不合理!
// ES6
"use strict"
function a(){
console.log(1);
}
function fn(){
a();
if(false){
function a(){
console.log(2)
}
}
}
fn();