ES6系列入門學習記錄:let和const

前言

感謝你能點進這篇文章,首先我先作一個說明,我是今年剛畢業的前端應屆生,這篇文章是我學習ES6的letconst部分以後,本身作的概括筆記,也是個人第一篇文章。第一次作這種文章類的分享,並且是在一個大平臺上,若是有不足,但願能夠幫我點出,十分感謝。前端

其實在發表文章以前,咱們公司前端組的大佬就一直鼓勵我去作文章分享,打造本身的一個品牌。可是因爲本身性格問題和懶惰,一直在拖。畢竟我最開始並不以爲本身有什麼能分享的,可是後續慢慢的才理解到一個真理:分享是沒有門檻的。因此開始嘗試作這種事情,但願能夠慢慢作好,畢竟也是對本身的一種提高和鍛鍊。以後會繼續更新ES6的學習記錄文章,文章的內容,都是經過本身理解以後,而後用本身的話語去進行一個描述,當中可能會有不太準確或者不太恰當的描述,也歡迎觀看文章的您提出這類的意見和建議。同時個人文章會進行一些內容的驗證,有些部分可能會驗證的有點多,也請多擔待。es6

最後補充一句,我目前ES6系列學習的主要文獻是阮一峯大神的《ECMAScript 6 入門》chrome

那就正式開始吧。瀏覽器

Let命令

let命令用於聲明變量,用法相似於var,可是let命令有個特色那就是隻會做用在let所在的做用域內。bash

Let命令的做用域

let a = 1;
{
    var b = 2;
    var c = a;
    let d = 3;
 }
 
 a // 1
 b // 2
 c // 1
 d // ReferenceError: b is not defined
複製代碼

這裏的a參數的let命令用法毫無心義,若是這樣使用就和var沒區別,倒不如說要這樣使用還不如使用varide

for循環則很是適合使用該命令函數

for(let i=0;i<1;i++){
   console.log('A',i);
}
console.log('B',i);

// A 0 
// ReferenceError: i is not defined
複製代碼

for循環中使用let命令,每一輪循環的i都是一個新的變量,若是在內部使用計算公式等,則會經過JavaScript引擎記住上一輪循環結果的值,而後對其進行後續的循環計算,總而完成計算。學習

for(let i = 0;i<3;i++){
  let i = 'a';
  console.log(i);
}

// a
// a
// a
複製代碼

此處是在for循環中使用let時候的一個特色,當子做用域中使用let再次定義了一個與父做用域中相同名稱的參數時,兩個參數互不干擾。測試

暫時性死區

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

let a = 1;
let b = 1;
{
   let a = 2;
   b = 2;
   console.log('a1',a);
   console.log('b1',b);
}
console.log('a2',a);
console.log('b2',b);

// a1 2
// b1 2
// a2 1
// b2 2
複製代碼

當分別在父做用域子做用域內使用let定義參數時,即使參數名相同,他們也不是同一個參數。父做用域中定義的參數,只會做用在自身做用域未從新使用let命令定義同名參數的子做用域中。該狀況就是自做用於中的let命令產生了暫時性死區。

var a = 1;
{
    console.log(a)
    let a = 2;
}

// ReferenceError: a is not defined
複製代碼

以上代碼可知,做用域內只要使用了let命令聲明的參數,即使有同名全局變量,也沒法在let命令代碼執行以前對該參數進行任意操做,即便這個操做和let命令是屬於同一個做用域

let的暫時性死區的特色, 會致使任意做用域,只要某個參數有對應的let聲明,不管該聲明的位置在哪,該做用域內的該參數,便會徹底獨立於在該做用域內,不會受到全局或者父做用域中同名參數的干擾。

不容許重複聲明

注意一點,let命令是個小貪心鬼,同做用域內不容許有其餘同名參數,不管是第二次同名命名是使用var仍是let,都會報錯。其子做用域中,也必須使用let命令進行同名命名,不然也會報錯。

let a = 1;
let a = 2;
console.log(a);

// Identifier 'a' has already been declared
複製代碼
var a = 1;
let a = 2;
console.log(a);

// Identifier 'a' has already been declared
複製代碼
let a = 1;
var a = 2
console.log(a);

// Identifier 'a' has already been declared
複製代碼
var a = 1;
var a = 2;
console.log(a);

//  2
複製代碼
let a = 1;
{
	var a = 2;
	console.log(a);
}
console.log(a);
複製代碼

以上代碼若在chrome調試面板測試時,請切記手動改參數名或者清除上一次代碼所命名的參數。

Let命令不存在變量提高

所謂變量提高,就是變量能夠在聲明代碼以前使用,不會出現報錯,不過值未undefinedvar便有該特色。

console.log(a);
var a = 1;
// undefined

console.log(b);
let b = 1;
// Identifier 'b' has already been declared
複製代碼

使用var命令聲明的參數,即會發生變量提高的參數,在腳本開始運行時,對應的變量就已經被建立,直到執行到實際定義參數的代碼時,該參數纔會被賦上對應的值。

塊級做用域與函數聲明

概念

在ES5中,通常只有全局做用域和函數做用域。

而在ES6中,增長了一個塊級做用域。ES6 規定,塊級做用域之中,函數聲明語句的行爲相似於let,在塊級做用域以外不可引用。

通常而言,每一個{}內部就是一個塊級做用域。

function f() { console.log('I am outside!'); }

(function () {
  if (false) {
    function f() { console.log('I am inside!'); }
  }

  f();}());
  
// Uncaught TypeError: f is not a function
複製代碼

上述代碼在ES6環境中執行的時候,會出現報錯,由於兩次聲明的function和執行的f()不在同一塊級做用域。

注意點

ES6改變了塊級做用域內聲明的函數的處理規則,可是因爲互聯網目前的現狀是多個版本環境同時並行的狀況。因此ES6有如下規定:

  • 容許在塊級做用域內聲明函數
  • 函數聲明相似於var,即會提高到全局做用域或函數做用域的頭部。
  • 同時,函數聲明還會提高到所在的塊級做用域的頭部。

以上規則只對ES6的瀏覽器生效。在其餘環境下不會生效。

綜上所述,咱們須要儘可能避免在塊級做用域內聲明函數。若是沒法避免,也要寫成函數表達式。而且塊級做用域的聲明函數規則,必須在使用{}的狀況下使用,不可使用簡寫。

if(true) 
    function f() {}
//報錯
複製代碼

const命令

概念

const用於聲明一個只讀的常量。

特色

因爲const聲明的常量爲只讀,因此其聲明的常量沒法修改。

const a = 123;

 a //123
 
 a = 321; // TypeError: Assignment to constant variable.
複製代碼

聲明的常量不能再次修改,因此意味着他必須在聲明的時候就進行賦值。由於若是不這樣作,你的聲明就沒有意義。

const a; // SyntaxError: Missing initializer in const declaration
複製代碼

constlet類似,只在塊級做用域內生效,同時也不提高和存在暫時性死區。

if(true){
   const a = 1;
}

a // ReferenceError: a is not defined


if(true){
   console.log(b);
   const b = 1;
}
//ReferenceError: b is not defined
複製代碼

同時也和let命令同樣,在同一塊級做用域內,不可重複使用同樣的名稱,即使一個是聲明常量,一個是聲明變量。

var a = 1;
   let b = 1;
   
   const a = 2; // SyntaxError: Identifier 'a' has already been declared
   const b = 2; // SyntaxError: Identifier 'b' has already been declared
複製代碼

本質

const並非變量的值不可改變,而是變量所指向的那個內存地址所保存的數據不得改變。特別是複合類型的數據,變量指向的內存地址,保存的只是一個指向實際數據的指針,const只能保證指針是固定的。

聽起來其實有點繞,我我的的理解是,好比你須要調某個倉庫的貨物,而後我告訴你倉庫的地址,我只能保障那個倉庫的位置在那裏不變,可是倉庫裏面放什麼我就沒法保證了。

const a = {};

a.prop = 1;
a.prop; // 1
複製代碼

所以,使用const聲明的時候須要格外當心,否則就是紅紅的報錯了。(雖然快過年了,可是代碼仍是別增添顧念的氣氛了)

一些小補充

頂層對象的屬性

在ES5中,頂層對象的屬性和全局變量是等價的,也就是說全局變量的a = 1 等同於 window.a = 1

ES6中,爲了改變這個狀況,給varfunction命令保留了原有的這個特性的同時。也規定了letconstclass等命令所聲明的全局變量,不屬於頂層對象的屬性。

var a = 1;
window.a //1

let b = a;
window.b //undefined
複製代碼

總結

第一篇結束了,一開始寫的時候特別亂,而後慢慢調整成了目前這一篇。若是你以爲還能夠,但願能夠幫點個贊。以後的更新我會繼續奉上,也但願能受到你的喜歡和收到你的意見和建議,十分感謝。

相關文章
相關標籤/搜索