ES6 筆記 | 2. let 和 const 命令

ES6 慢慢學~

1 /

ES5 只有兩種聲明變量的方法:var命令和function命令。javascript

ES6 除了添加let命令和const命令,另外兩種聲明變量的方法:import命令和class命令。java

因此,ES6一共有6 種聲明變量的方法es6

我在這與你共同進步

  1. var命令能夠聲明變量
  2. function命令聲明函數,後跟一組參數及函數體
  3. let命令用於聲明變量
  4. const命令聲明一個只讀的常量
  5. 經過export命令顯式指定輸出的代碼,再經過import命令輸入
  6. class關鍵字能夠定義類

2 /

let命令和const命令所聲明的變量or常量只在它所在的代碼塊有效數組

const實際上保證的,並非變量的值不得改動,而是變量指向的按個內存地址所保存的數據不得改動。數據結構

  • 對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,所以等同於常量。
  • 對於複合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針。const 只能保證這個指針是固定的(即老是指向另外一個固定的地址),至於它指向的數據結構是否是可變的,就徹底不能控制了。
  • const 只聲明不賦值,就會報錯
for (let i = 0; i < 4; i++) {
    // ...
}
console.log(i);
// ReferenceError: i is not defined
const student = {};
// 能夠添加一個屬性
student.name = '朝霞的世界';
// 將 student 指向另外一個對象,就會報錯
student = {}; // TypeError: "student" is read-only

3 /

ES5 只有全局做用域和函數做用域,沒有塊級做用域,這樣會有一些不合理的場景。函數

  1. 內層變量可能會覆蓋外層變量
  2. 用來計數的循環變量泄露爲全局變量
var tmp = new Date();

function f() {
    console.log(tmp);
    if (false) {
        var tmp = 'zhaoxiajingjing';
    }
}

f(); // undefined
var s = 'hello';

for (var i = 0; i < s.length; i++) {
    console.log(s[i]);
}

console.log(i); // 5

看10遍不如寫1遍

ES6 新增了塊級做用域,容許任意嵌套。使得自執行匿名函數表達式就再也不必要了。spa

{{{{
  {let insane = 'zhaoxiajingjing'}
  console.log(insane); // 報錯
}}}};
// 自執行匿名函數
(function () {
    var tmp = ...;
}());
// 塊級做用域寫法
{
    let tmp = ...;
}

4 /

只要塊級做用域內存在let命令或const命令,它所聲明的變量或常量就「綁定」(binding)這個區域,再也不受外部影響。3d

在代碼塊內,使用let命令聲明變量以前,該變量都是不可用的。這在語法上,稱爲:暫時性死區(temporal dead zone,簡稱TDZ)指針

if (true) {
    // TDZ開始
    tmp = 'zhaoxiajingjing'; // ReferenceError
    console.log(tmp); // ReferenceError
    let tmp; // TDZ結束
    console.log(tmp); // undefined
    tmp = 123;
    console.log(tmp); // 123
}

5 /

letconstPK var
  1. 有效範圍var聲明的變量,會聲明到全局,污染全局變量
  2. 變量提高var聲明的變量,能夠在聲明以前調用
  3. 做用域:使用var的做用域有全局做用域、函數做用域
  4. 重複聲明var能重複聲明
1.有效範圍
  • letconst只在聲明所在的塊級做用域內有效
  • var聲明的變量,會聲明到全局,污染全局變量
var a = [];
for (var i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    };
}
a[6](); // 10
window.a[4](); // 10
window.i; // 10

上面代碼中,變量 ivar命令聲明的,在全局範圍內有效,因此全局只有一個變量i。能夠在window上訪問並獲取到值。code

var a = [];
for (let i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    };
}
a[6](); // 6
window.a[4](); // 4
window.i; // undefined

上面代碼中,變量ilet聲明的,當前的i只在本輪循環有效,因此每一次循環的i都是一個新的變量,因此每次輸出的值不同。

let聲明的變量僅在塊級做用域內有效,因此在windowi的值是undefined

for循環還有一個特別之處,就是設置循環變量的那部分是一個父做用域,而循環體內部是一個單獨的子做用域。
for (let i = 0; i < 3; i++) {
    let i = 'zhaoxiajingjing';
    console.log(i);
}
// zhaoxiajingjing
// zhaoxiajingjing
// zhaoxiajingjing
2.變量提高
  • letconst聲明的變量or常量不會提高,必定要在聲明後使用,不然報錯
  • var聲明的變量,能夠在聲明以前調用,值爲undefined
// var 的狀況
console.log(a); // 輸出undefined
var a = 2;

// let 的狀況
console.log(b); // 報錯ReferenceError
let b = 2;
3.做用域
  • letconst能夠在塊級做用域中使用
  • 使用var的做用域有全局做用域、函數做用域
{
    var a = 'hello';
    let gzh = 'zhaoxiajingjing';
}
console.log(a); // hello
console.log(gzh); // ReferenceError: gzh is not defined
4.重複聲明
  • letconst不容許在相同做用域內,重複聲明同一個變量
  • var能重複聲明
// 報錯
function f(){
    let gongzhonghao = 'zhaoxiajingjing';
    var gongzhonghao = 'zhaoxiajingjing';
}
f();
// 不報錯
function f(){
    var gongzhonghao = 'zhaoxiajingjing';
    var gongzhonghao = 'zhaoxiajingjing';
}
f();
// 報錯
function f(args){
    let args = 'zhaoxiajingjing';
}
f();
// 不報錯
function f(args){
    {
        let args = 'zhaoxiajingjing';
    }
}
f();

zhaoxiajingjing

思考 /

  1. 函數能不能在塊級做用域之中聲明?
  2. 暫時性死區對typeof有什麼影響?
參考:ECMAScript 6 入門
http://es6.ruanyifeng.com/#do...

文章首發公衆號

相關文章
相關標籤/搜索