ES6(let 與 const、Template Literals)


Posted by saffran on 2021-02-05

ES5?ES6?這些到底是什麼

ECMAScript 就是一個「標準、規範」,開發者可以根據這個規範去開發程式語言

而 JavaScript 這個程式語言就是根據 ECMAScript 去實作的

  • ECMAScript 5 (簡稱 ES5)是比較舊的 JavaScript 語法
  • ES6 在 2015 年正式發佈,有新增一些 JavaScript 的語法、功能
    因此 ES6 又稱為 ES2015

宣告變數的新選擇:let 與 const

const

const 的全名是 constant(常數),是「不能改變」的

使用時機:
有些變數,我已經知道它是不會變的,就可以用 const 來宣告

對於 primitive type 來說,用 const 宣告的變數是「值」不能改變

例如:
我用 const 宣告變數 b (是一個 number,屬於 primitive type),變數裡面是直接存「值」

因此,變數 b 的「值」是不能改變的

如果我把變數 b 的值改成 20

console.log(b) 就會出現錯誤:Assignment to constant variable.(你不可以改變一個 constant variable)

const b = 9
b = 20

console.log(b)

對於 object 來說,用 const 宣告的變數是「記憶體位置」不能改變

(object 可以是物件或陣列)

例如:
我用 const 宣告變數 b(是一個物件,屬於 object),變數裡面存的是「記憶體位置」

因此,我用 b.number = 30 修改 number 的 value

結果發現是可以更改的!

const b = {
  number: 10
}
b.number = 30

console.log(b)
// output: { number: 30 }

原因是:
「用 const 宣告的變數,不能改變」,對於 object 來說是指:「物件/陣列裡面存的 “記憶體位置” 不能改變」,如果只是更改 b.number = 30 並沒有改動到記憶體位置,b.number = 30 只是去改「那個記憶體位置上的物件的 value」而已,因此是可以更改的!(用這種 . 的方式去修改物件裡面的值)

但是,如果是把一個「新的物件」賦予給變數 b,那就不行了,因為新的物件會是「新的記憶體位置」

例如:
下面這樣寫就會出現錯誤:Assignment to constant variable(你不可以改變一個 constant variable)

const b = {
  number: 10
}

b = {
  number: 99
}

console.log(b)

var 跟 let, const 的差別是什麼?

要了解 var 跟 let, const 的差別,首先要了解「作用域」的概念:

作用域(Scope)

作用域,就是「變數的生存範圍」

變數的運行機制:從「最近的」開始找,先找到的先贏

例如:

範例一:在 function 外面宣告變數 a

變數 a 是「全域變數」

因為我在外層宣告的變數 a 是在「檔案的這層」,所以,如果 test function 裡面沒有宣告 a,它就會往上層找,直到找到 a 為止,因此就會找到 var a = 20

var a = 20
function test(){
  console.log(a)
}

test()
// output: 20

範例二:function 裡面有宣告變數 a
因為在 test function 裡面就有宣告 a,所以它在 function 裡面就找到 a

var a = 20
function test(){
  var a = 99
  console.log(a)
}

test()
// output: 99

區域變數

因為我是在 test function 裡面宣告變數 a,所以變數 a 的作用域就只存在 test function 裡面

變數 a 是「區域變數」

test function 外面是無法使用變數 a 的

因此,console.log(a) 就會出現錯誤:a is not defined

function test(){
  var a = 20
}

test()
console.log(a)

用 var 宣告的變數,變數的作用域會是「一個 function」

例如:
雖然我是在 if 的區塊(block)宣告變數 a,但只要是在 test function 裡面,就都是變數 a 的作用域

因此,console.log(a) 可以存取到 a 的值

function test(){
  if(10 > 5){
    var a = 10
  }
  console.log(a)
}

test()
// output: 10

用 let 或是 const 宣告的變數,變數的作用域會是「一個 block」而已

例如:
用 let 宣告變數
我是在 if 的區塊(block)內,用 let 宣告變數 a,因此變數 a 的作用域就只會在 if 這個 block 內而已:

  if(10 > 5){
    let a = 10
  }

所以,在 if 區塊外面的 console.log(a) 就會出現錯誤:a is not defined

function test(){
  if(10 > 5){
    let a = 10
  }
  console.log(a)
}

test()

用 const 宣告變數
我是在 if 的區塊(block)內,用 const 宣告變數 a,因此變數 a 的作用域就只會在 if 這個 block 內而已

所以,在 if 區塊外面的 console.log(a) 就會出現錯誤:a is not defined

function test(){
  if(10 > 5){
    const a = 10
  }
  console.log(a)
}

test()

使用時機

  • 如果變數會改變,就用 let 宣告
  • 如果變數不會改變,就用 const 宣告
    例如:const PI = 3.14
  • 盡量用 let, const 來宣告變數(基本上不會需要用 var 這個關鍵字)
    原因是:會希望作用域越小越好,這樣才不容易干擾到其他變數(例如:取了同名的變數,就不會互相干擾),也比較容易 debug

字串拼接好麻煩,改用 Template Literals 吧

在 ES5 時,使用 string 會遇到幾個問題:

[問題一] 字串需要換行時

有多行字串時,無法直接換行(下面這樣寫,是會出錯的)

let str = '
hello
I
love
you
'

字串要換行就要用這種「字串拼接」的方式,很麻煩

let str = 
  'hello' + '\n' +
  'I' + '\n' +
  'love' + '\n' +
  'you'

console.log(str)

output:

hello
I
love
you

[問題二] 當我有很多字串 + 變數需要拼接時

單引號、加號如果放錯位置,就很容易造成語法錯誤,這樣很麻煩

function sayHi(name){
  console.log('Hello, ' + name + '! It is ' + new Date() + ' now.')
}

sayHi('Dan')
// output: Hello, Dan! It is Thu Jul 09 2020 15:28:20 GMT+0800 (Taipei Standard Time) now.

用 ES6 的 `` 來寫字串

字串可以直接換行,好方便

`` 這個反引號來包住字串,字串就可以直接換行了

let str = `
hello
I
love
you
`
console.log(str)

output:

hello
I
love
you

${ } 插入 JS 程式碼,好方便

${ }裡面,可以放 JavaScript 的程式碼,最常放在裡面的就是「JavaScript 的變數」

function sayHi(name){
  console.log(`Hello, ${name}! It is ${new Date()} now.`)
}

sayHi('Dan')
// output: Hello, Dan! It is Thu Jul 09 2020 15:39:22 GMT+0800 (Taipei Standard Time) now.

也可以直接在 ${ }裡面執行一些 function,例如: ${name.toUpperCase()} 就會把 name.toUpperCase() 的回傳值,放到字串裡面

function sayHi(name){
  console.log(`Hello, ${name.toUpperCase()}! It is ${new Date()} now.`)
}

sayHi('Daniel')
// output: Hello, DANIEL! It is Thu Jul 09 2020 15:43:35 GMT+0800 (Taipei Standard Time) now.

#javascript







Related Posts

Day 17-OOP & Quiz Game

Day 17-OOP & Quiz Game

[ React 筆記 ] input使用useRef存取子元件

[ React 筆記 ] input使用useRef存取子元件

W21 + W22_React 學習筆記

W21 + W22_React 學習筆記


Comments