一.let
let命令的基本用法和 var 差不多,幾乎一樣,就是用來聲明變量的,爲什麼有了var 還要有一個let呢?我找到了幾個答案
1.es6之前,js和普通的程序開發語言有很大不同,它的一些特點(缺點)讓它夠不上一項程序語言的標準。其中在變量聲明這一點有些不合理。es6推薦使用let聲明變量就是想要讓js逐漸走上一條標準的開發語言之路。
2.var 不廢除,也是爲了兼容,估計有一天var就會看不見了 。總之,let讓js開發更標準,更易理解,更減少錯誤,等。
1.let不存在變量提升
變量提升: 變量在聲明之前就可以使用(undefined), 表現類似於變量在所有執行代碼之前就已經聲明過。 (var 是變量提升的)
a = 123
var a ;
console.log(a) //123
a = 123
let a;
console.log(a) //error
優點: 開發中不必擔心隨手聲明瞭變量,有可能導致變量覆蓋,污染,而且使得開發更加嚴謹,出錯率少。
2.let變量的暫時性死區
暫時性死區: 代碼塊內,變量聲明之前,變量不可用,前提是這個代碼塊內必須存在這個變量的聲明,如果不存在,訪問外部作用域。
let a = 456
if(true){
a = 123 //error
let a;
}
這個特性使得typeof方法不一定安全,也是爲了讓開發者習慣於在變量聲明之後再使用變量。3.let變量不允許重複聲明
確切的說是不允許在同一作用域中重複聲明
二.塊級作用域
es6之前只有全局和函數作用域,不存在塊級作用域,所以出現了一些很奇怪的現象
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
if代碼塊裏面的內容在不存在塊級作用域的情況下,相當於直接在函數中,也就是說,函數中存在tmp變量聲明(變量提升),所以輸出undefined,可是這個結果和想要的不一樣。
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
循環使用的變量變成了全局變量,因爲不存在塊級作用域,所以直接是全局作用域。
1.es6塊級作用域
es6新增了塊級作用域,這個塊級作用域基於let命令,在代碼塊中,使用let命令聲明變量,則在這個代碼塊中形成自己的作用域(只用let命令聲明的變量有效,var 無效)
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
2.函數聲明在塊級作用域中
es5不允許在代碼塊中聲明函數,但是es6允許,es6在代碼快中聲明的函數相當於使用let一樣的性質,存在塊級作用域。
塊級作用域總結: es6的塊級作用域是存在的,這一切的基礎在於-變量需要let聲明,函數則沒有限制
三.const
const 用來聲明常量,它和let用相同的特性,只是它聲明的變量指向的值不可修改而已(不存在變量提升,暫時性死區都存在),所以常量也需要先聲明再使用啊。
注意: const 變量指向的值不可改變,仔細想想,在聲明基本類型(字符串,數字,bool),它的變量確實是不可改變的,因爲變量指向‘值’, 但是在聲明引用類型(對象)的時候,指向的值就是引用的指針而已,指針不可以改變,但是其中的值可以改變啊。
const foo = {};
// 爲 foo 添加一個屬性,可以成功
foo.prop = 123;
foo.prop // 123
// 將 foo 指向另一個對象,就會報錯
foo = {}; // TypeError: "foo" is read-only
在用const 聲明引用類型變量的時候,一定要注意。
這裏使用的的例子,參照阮一峯的es6入門