天天看點

ES6研習:let和const指令

ES6研習:let和const指令

1.

let

指令

基本用法 :

ES6 新增了

let

指令,用來聲明變量。

注意:所有生命的變量旨在

let

指令所在代碼塊中有效,也就是

{}

{
  let a = 10;
  var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
           

1.1 不存在變量提升

變量提升 :

var

指令會發生“變量提升”現象,即變量可以在聲明之前使用,值為

undefined

這樣很容易出現各種問題,

let

聲明的變量不存在變量提升

// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;

// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;
           

1.2暫時性死區

在代碼塊内,使用

let

指令聲明變量之前,該變量都是不可用的。這在文法上,稱為“暫時性死區”(temporal dead zone,簡稱 TDZ)。
if (true) {
  // TDZ開始
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ結束
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}
           

注意:沒有變量提升和有暫時性死區後,typeof關鍵字可能會報錯

因為之前使用

var

關鍵字,沒有聲明的變量值都為

undefined

typeof x; // ReferenceError
let x;
typeof undeclared_variable // "undefined"
           

還有一些情況會報錯:

function bar(x = y, y = 2) {
  return [x, y];
}
bar(); // 報錯

function bar(x = 2, y = x) {
  return [x, y];
}
bar(); // [2, 2]

// 不報錯
var x = x;

// 報錯
let x = x;
// ReferenceError: x is not defined
           

總結 : 在ES6中使用

let

關鍵字聲明變量都應該先聲明再使用,這樣也可以避免很多不必要的錯誤

1.3不允許重複聲明

let

不允許在相同作用域内,重複聲明同一個變量。

// 報錯
function func() {
  let a = 10;
  let a = 1;
}

function func(arg) {
  let arg;
}
func() // 報錯
           

1.4塊級作用域

ES5中有全局作用域和函數作用域,ES6添加塊級作用域。

ES5中的

var

關鍵字在很多時候都是不合理的,不管是變量提升還是作用域
ES6新增的塊級作用域可以了解為

{}

塊級作用域的特點 :

  • 外層作用域無法讀取内層作用域的變量
  • 内層作用域可以定義外層作用域的同名變量。
  • 有了塊級作用域後就可以不需要立即執行函數了,解決了循環中的很多問題,像定時器,閉包等
// IIFE 寫法
(function () {
  var tmp = ...;
  ...
}());

// 塊級作用域寫法
{
  let tmp = ...;
  ...
}
           

注意:不要忘記在循環語句的

()

裡面會形成一個單獨的作用域

2.

const

指令

const

聲明一個隻讀的常量。一旦聲明,常量的值就不能改變。

2.1 基本用法

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.
           

const特點 :

  • 聲明常量,一旦聲明不能改變
  • 一旦聲明,必須指派不可以留到以後指派
  • 不存在變量提升,同樣存在暫時性死區,隻能聲明後使用

2.2 實質

  • const

    不是保證值不變,而是保證變量指向的位址不變,對于基本資料類型變量是直接指向記憶體位址的,是以等同于常量
  • 但是對于對象而言,記憶體儲存的是一個指針,是以使用

    const

    聲明對象時不能重新指派其他對象但是可以為其添加屬性
const foo = {};

// 為 foo 添加一個屬性,可以成功
foo.prop = 123;
foo.prop // 123

// 将 foo 指向另一個對象,就會報錯
foo = {}; // TypeError: "foo" is read-only
           

2.3當機對象

如果真的想将對象當機,應該使用

Object.freeze

方法。
const foo = Object.freeze({});

// 正常模式時,下面一行不起作用;
// 嚴格模式時,該行會報錯
foo.prop = 123;
           

除了将對象本身當機,對象的屬性也應該當機。下面是一個将對象徹底當機的函數。

var constantize = (obj) => {
  Object.freeze(obj);
  Object.keys(obj).forEach( (key, i) => {
    if ( typeof obj[key] === 'object' ) {
      constantize( obj[key] );
    }
  });
};
           

個人部落格:http://www.aeiherumuh10.com/zeno-blog/

參考文獻:https://es6.ruanyifeng.com/#docs/let

繼續閱讀