JavaScript學習筆記(十三) ES6新特性

這篇文章我們將會介紹 ES2015 / ES6 中一些常用的新特性

1、變量定義

在 ES6 之前,定義變量只能使用 var 關鍵字,而在 ES6 中新增 letconst 關鍵字,它們之間的區別如下:

關鍵字 作用域 變量是否提升 能否重複定義
var 函數作用域
letconst 塊級作用域
function function_scope() {
    console.log(result) // undefined
    var result = 0
    for (var count = 1; count <= 5; count++) { result += count }
    console.log(count) // 5
    return result
}

function block_scope() {
    // console.log(result) -> ReferenceError: result is not defined
    let result = 0
    for (let count = 1; count <= 5; count++) { result += count }
    // console.log(count) -> ReferenceError: count is not defined
    return result
}

letconst 之間的區別如下:

  • 使用 const 定義的變量在聲明時必須賦值,而 let 不用
  • 使用 const 定義的變量聲明之後不能修改,而 let 不會
// const a -> Uncaught SyntaxError: Missing initializer in const declaration
const a = 0
// a = 1 -> Uncaught TypeError: Assignment to constant variable.

注意哦,這裏所說的不能修改,並不是說變量的值不可修改,而是變量的標識符不能重新分配

準確而言,const 聲明的變量是一個值的只讀引用,它意味着棧空間的地址不可修改,而非堆空間中的值不可修改

因此對於引用類型,我們還是可以修改它的值的

const a = [1, 3, 5]
a[0] = 2
console.log(a) // (3) [2, 3, 5]

2、數組迭代

在 ES6 之前,使用 for 循環迭代數組有兩種方式,分別是傳統 for 循環和 for...in 循環

let array = ['a', 'b', 'c']
// 傳統 for 循環
for (let index = 0; index < array.length; index++) {
    console.log(index + ': ' + array[index])
}
// for...in 循環
for (let index in array) {
    console.log(index + ': ' + array[index])
}

/*
 * 執行結果:
 * 0: a
 * 1: b
 * 2: c
**/

而在 ES6 中新增 for...of 循環,可以直接遍歷數組元素,而非數組索引

let array = ['a', 'b', 'c']
// for...of 循環
for (let item of array) {
    console.log(item)
}

/*
 * 執行結果:
 * a
 * b
 * c
**/

for...of 循環中還可以使用 continuebreak 語句

let array = [1, 2, 3, 4, 5, 6, 7, 8]
let sum = 0
for (let item of array) {
    if (item % 2 === 0) continue
    sum += item
}
console.log(sum) // 16

3、模板字符串

模板字符串在多行字符串和字符串拼接等場景下十分方便

  • ES6 之前
// 多行字符串
let html = '<ul>' + 
    '<li>Apple</li>' +
    '<li>Banana</li>' +
    '<li>Cherry</li>' +
    '</ul>'
console.log(html)
// 字符串拼接
let protocol = 'https'
let host = '127.0.0.1'
let port = '80'
let path = 'index.html'
let url = protocol + '://' + host + ':' + port + '/' + path
console.log(url) /* http://127.0.0.1:80/index.html */
  • ES6 之後
// 多行字符串,保留原有格式
let html = `
<ul>
    <li>Apple</li>
    <li>Banana</li>
    <li>Cherry</li>
</ul>
`
console.log(html)
// 字符串拼接,可以使用變量
let protocol = 'https'
let host = '127.0.0.1'
let port = '80'
let path = 'index.html'
let url = `${protocol}://${host}:${port}/${path}`
console.log(url) /* http://127.0.0.1:80/index.html */

4、解構語法

解構語法可以將數組和對象中的值提取出來並賦值給新的變量

  • ES6 之前
// 數組解構
let array = ['a', 'b', 'c']
let x = array[0]
let y = array[1]
let z = array[2]
console.log(x, y ,z) // a b c
// 對象解構
let object = { name: 'Steve', age: 18 }
let name = object.name
let age = object.age
console.log(name, age) // Steve 18
  • ES6 之後
// 數組解構
let array = ['a', 'b', 'c']
let [x, y, z] = array
console.log(x, y, z) // a b c
// 對象解構,變量名要與屬性名相同
let object = { name: 'Steve', age: 18 }
let { name, age } = object
console.log(name, age) // Steve 18

解構語法還可以設置默認值和重命名變量

// 設置默認值
let array = ['a', 'b']
let [x = 'x', y = 'y', z = 'z'] = array
console.log(x, y, z) // a b z
// 重命名變量
let object = { name: 'Steve', age: 18 }
let { name: nickName, age: nominalAge } = object
console.log(nickName, nominalAge) // Steve 18

5、擴展運算符

  • ES6 之前
// 數組複製
let array = ['a', 'b', 'c']
let array_copy = array.concat()
console.log(array_copy) // (3) ["a", "b", "c"]
// 數組合並
let array_one = ['a', 'b', 'c']
let array_two = ['d', 'e', 'f']
let array_merge = array_one.concat(array_two)
console.log(array_merge) // (6) ["a", "b", "c", "d", "e", "f"]
// 接收函數參數,所有傳入的參數都會保存在 arguments 中
function add() {
    let result = 0
    Array.prototype.forEach.call(arguments, function(item) { result += item })
    return result
}
let result = add(1, 2, 3)
console.log(result) // 6
  • ES6 之後
// 數組複製
let array = ['a', 'b', 'c']
let array_copy = [...array]
console.log(array_copy) // (3) ["a", "b", "c"]
// 合併數組
let array_one = ['a', 'b', 'c']
let array_two = ['d', 'e', 'f']
let array_merge = [...array_one, ...array_two]
console.log(array_merge) // (6) ["a", "b", "c", "d", "e", "f"]
// 接收函數參數,剩餘參數作爲函數的最後一個參數,將傳入的參數以數組的形式儲存起來
function add(...array) {
    let result = 0
    array.forEach(function(item) { result += item })
    return result
}
let result = add(1, 2, 3)
console.log(result) // 6

6、默認參數

在定義函數的時候,可以直接爲函數參數設置默認值

  • ES6 之前
function greet(somebody) {
    var somebody = somebody || 'stranger'
    console.log('Hello, ' + somebody)
}
greet('Amy') // Hello, Amy
greet() // Hello, stranger
  • ES6 之後
function greet(somebody = 'stranger') {
    console.log('Hello, ' + somebody)
}
greet('Amy') // Hello, Amy
greet() // Hello, stranger

7、箭頭函數

使用箭頭函數不僅可以更加方便的定義函數,而且 this 的值將會繼承父級執行上下文 this 的值

  • ES6 之前
// 過濾奇數,元素累加
let sum = 0
let arr = [1, 2, 3, 4, 5]
let even = arr.filter(function(item) { return item % 2 === 0 })
even.forEach(function(item) { sum = sum + item })
console.log(sum) // 6
// this 取值
let object = {
    value: 'hello',
    print: function() {
        // 使用 bind 函數將 this 的值綁定好
        setTimeout(function() { console.log(this.value) }.bind(this), 1000)
    }
}
object.print() // hello
  • ES6 之後
// 過濾奇數,元素累加
let sum = 0
let arr = [1, 2, 3, 4, 5]
let even = arr.filter((item) => (item % 2 === 0))
even.forEach((item) => { sum = sum + item })
console.log(sum) // 6
// this 取值
let object = {
    value: 'hello',
    print: function() {
        // 使用箭頭函數,this 的值將會繼承父級執行上下文(在這裏是 print 函數)this 的值
        setTimeout(() => { console.log(this.value) }, 1000)
    }
}
object.print() // hello

【 閱讀更多 JavaScript 系列文章,請看 JavaScript學習筆記

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章