ES6學習(一)之var、let、const

更多前端文章

一、變量提高

概述:變量可在聲明以前使用。前端

console.log(a);//正常運行,控制檯輸出 undefined
var a = 1;
console.log(b);//報錯,Uncaught ReferenceError: b is not defined
let b = 1;
console.log(c);//報錯,Uncaught ReferenceError: c is not defined
const c = 1;

var 命令常常會發生變量提高現象,按照通常邏輯,變量應該在聲明以後使用纔對。爲了糾正這個現象,ES6 規定 let 和 const 命令不發生變量提高,使用 let 和 const 命令聲明變量以前,該變量是不可用的。主要是爲了減小運行時錯誤,防止變量聲明前就使用這個變量,從而致使意料以外的行爲。git

二、暫時性死區

概述:若是在代碼塊中存在 let 或 const 命令,這個區塊對這些命令聲明的變量,從一開始就造成了封閉做用域。凡是在聲明以前就使用這些變量,就會報錯。es6

var tmp = 123;
if (true) {
    tmp = 'abc';//報錯,Uncaught ReferenceError: tmp is not defined
    let tmp;
}

剖析暫時性死區的原理,其實let/const一樣也有提高的做用,可是和var的區別在於github

  • var在建立時就被初始化,而且賦值爲undefined
  • let/const在進入塊級做用域後,會由於提高的緣由先建立,但不會被初始化,直到聲明語句執行的時候才被初始化,初始化的時候若是使用let聲明的變量沒有賦值,則會默認賦值爲undefined,而const必須在初始化的時候賦值。而建立到初始化之間的代碼片斷就造成了暫時性死區

三、不容許重複聲明

let不容許在相同做用域內,重複聲明同一個變量。數組

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

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

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

四、塊級做用域

在es5中咱們會遇到下面這寫狀況
第一種場景,內層變量可能會覆蓋外層變量。數據結構

var tmp = new Date();
function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';//沒有塊級做用域tmp變量提高到函數做用域裏致使tmp爲undefined
  }
}
f(); // undefined

第二種場景,用來計數的循環變量泄露爲全局變量。函數

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

上面代碼中,變量i只用來控制循環,可是循環結束後,它並無消失,泄露成了全局變量。es5

let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

let實際上爲 JavaScript 新增了塊級做用域。指針

五、const注意點

一、const聲明變量的時候必須賦值,不然會報錯,一樣使用const聲明的變量被修改了也會報錯
二、const聲明變量不能改變,若是聲明的是一個引用類型,則不能改變它的內存地址code

const c ; //Uncaught SyntaxError: Missing initializer in const declaration
const a= {a:1};
a.a=2;
a={d:2};// Uncaught TypeError: Assignment to constant variable.
本質:const實際上保證的,並非變量的值不得改動,而是變量指向的那個內存地址所保存的數據不得改動。對於簡單類型的數據(數值、字符串、布爾值),值就保存在變量指向的那個內存地址,所以等同於常量。但對於複合類型的數據(主要是對象和數組),變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證這個指針是固定的(即老是指向另外一個固定的地址),至於它指向的數據結構是否是可變的,就徹底不能控制了

那麼咱們想獲得不可修改的const要怎麼作呢?應該使用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] );
    }
  });
};

參考文章
ECMAScript 6 入門

相關文章
相關標籤/搜索