JavaScriptES6中的前五項功能值得掌握

JavaScriptES6爲JavaScript語言添加了一系列新特性,其中一些特性更具有開拓性,而且比其他特性更適用。像ES6類例如,雖然新穎,但在現有的JavaScript類創建方法的基礎上添加了語法糖,而生成器等功能雖然非常強大,但卻保留給更專門的任務。

從過去12個月從事各種JavaScript相關項目來看,我發現ES6的五個最重要的特性是必不可少的,因爲它們真正簡化了JavaScript中常見任務的完成方式。你的前五名可能與我的不同,如果他們是,我鼓勵你分享在評論部分的結尾。

開始吧!

  1. 箭頭函數

  2. 承諾

  3. 異步函數

  4. 解構

  5. 默認和REST參數

1)JavaScript Arrow函數

在ES6JavaScript中,我最喜歡的一個新增功能不是一個新特性,而是一個令人耳目一新的新語法集,每當我使用它時,它都會讓我面帶微笑。我說的是Arrow函數,它提供了一種非常優雅和極簡的方法來定義JavaScript中的匿名函數。

簡而言之,Arrow函數會刪除“function“關鍵字,並使用箭頭(=>)將函數的函數體中的參數部分。匿名職能:

1
(x, y) => x * y;

這相當於:

1
2
3
function(x, y){
    return x * y;
}

或:

1
2
3
4
(x, y) => {
    var factor = 5;
    var growth = (x-y) * factor;
}

與以下內容相同:

1
2
3
4
function(x, y){
    var factor = 5;
    var growth = (x-y) * factor;
}

使用傳統的匿名函數時,箭頭函數還移除一個關鍵錯誤源,即this“函數中的對象。使用Arrow函數,“this“在詞彙上是綁定的,這是只是一種奇特的表達方式,它的值被綁定到父範圍,並且永不改變。如果 箭函數在自定義對象中定義爲“countup的價值this“指向”countup“-沒有任何猜測。例如:

1
2
3
4
5
6
7
8
9
10
11
var countup = {
    counter: 15,
      
    start:function(){
        window.addEventListener('click', () => {
            alert(this.counter) // correctly alerts 15 due to lexical binding of this
        })
    }
};
  
countup.start();

將其與傳統的匿名函數進行比較,其中“this“更改取決於在其中定義的上下文。試圖引用的結果this.counter在上述情況下將返回undefined這種行爲可能會使許多人不熟悉動態綁定的複雜性。對於Arrow函數,“this“總是可以預測和容易推斷的。

有關“箭上的瘦身”功能,請參閱“JavaScriptArrow函數概述".

2)JavaScript承諾

JavaScriptES6承諾簡化異步任務的處理方式,這是一個在大多數現代Web應用程序中發揮作用的任務。JavaScript承諾使用一種中心的、直觀的機制來跟蹤和響應異步事件,而不是依賴回調函數(由jQuery等JavaScript框架推廣)。它不僅使調試異步代碼變得更加容易,而且編寫異步代碼也是一種樂趣。

所有JavaScript承諾的生存和死亡Promise()構造者:

1
2
3
4
5
const mypromise = new Promise(function(resolve, reject){
 // asynchronous code to run here
 // call resolve() to indicate task successfully completed
 // call reject() to indicate task has failed
})

使用resolve()reject()方法在內部,當承諾被履行和拒絕時,我們可以分別向承諾對象發出信號。這,這個,那,那個then()catch()然後可以調用方法來處理完全填充或被拒絕的承諾的後果。

我一直使用以下承諾的變體注入XMLHttpRequest函數,依次檢索外部文件的內容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function getasync(url) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open("GET", url)
        xhr.onload = () => resolve(xhr.responseText)
        xhr.onerror = () => reject(xhr.statusText)
        xhr.send()
    })
}
 
getasync('test.txt').then((msg) => {
    console.log(msg) // echos contents of text.txt
    return getasync('test2.txt')
}).then((msg) => {
    console.log(msg) // echos contents of text2.txt
    return getasync('test3.txt')
}).then((msg) => {
    console.log(msg) // echos contents of text3.txt
})

要掌握JavaScript承諾的關鍵方面,例如鏈接承諾和並行執行承諾,請閱讀“承諾初學者指南".

3)JavaScript異步函數

除了JavaScript承諾之外,異步函數還進一步重寫了傳統異步代碼的構造,使其更加可讀性更強,更易於理解。每當我向客戶顯示代碼時async 函數交織在一起,第一反應總是令人驚訝,接着是強烈的好奇心,以瞭解它是如何工作的。

異步函數由兩部分組成:

1)以前綴爲前綴的正則函數async功能

1
2
3
4
async function fetchdata(url){
    // Do something
    // Always returns a promise
    }

2)使用await關鍵字在主異步函數中異步函數調用之前。

一個例子勝過千言萬語。下面是上面基於承諾的示例的重寫,以供使用異步函數相反:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function getasync(url) { // same as original function
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open("GET", url)
        xhr.onload = () => resolve(xhr.responseText)
        xhr.onerror = () => reject(xhr.statusText)
        xhr.send()
    })
}
 
async function fetchdata(){ // main Async function
    var text1 = await getasync('test.txt')
    console.log(text1)
    var text2 = await getasync('test2.txt')
    console.log(text2)
    var text3 = await getasync('test3.txt')
    console.log(text3)
    return "Finished"
}
 
fetchdata().then((msg) =>{
    console.log(msg) // logs "finished"
})

上面的示例在運行時按順序回顯“test.txt”、“test2.txt”、“test3.txt”以及最後“Finish”的內容。

如您所見,在異步函數,我們調用異步函數。getasync()好像是同步的-不then()方法或回調函數,以向下一步發出信號。無論何時await關鍵字時,執行將暫停,直到 getasync()在移到異步函數中的下一行之前已解析。結果與基於純承諾的方法相同,使用了一系列的then()方法。

掌握異步函數,包括如何執行await函數並行,讀爲“JavaScript異步函數簡介-承諾簡化".

4)JavaScript析構

除了Arrow函數之外,這是我每天使用最多的ES6功能。ES6解構不是一種新特性,而是一種新的賦值語法,它允許您快速地從對象屬性和數組中解壓縮值,並將它們分配給各個變量。

1
2
3
4
var profile = {name:'George', age:39, hobby:'Tennis'}
var {name, hobby} = profile // destructure profile object
console.log(name) // "George"
console.log(hobby) // "Tennis"

在這裏,我使用析構來快速提取namehobby屬性的profile對象。

使用別名,您可以使用不同的變量名,而不是從其中提取值的對應對象屬性:

1
2
3
4
var profile = {name:'George', age:39, hobby:'Tennis'}
var {name:n, hobby:h} = profile // destructure profile object
console.log(n) // "George"
console.log(h) // "Tennis"

嵌套對象析構

析構也適用於嵌套對象,我一直使用這些對象來快速解壓縮複雜JSON請求中的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var jsondata = {
    title: 'Top 5 JavaScript ES6 Features',
    Details: {
        date: {
            created: '2017/09/19',
            modified: '2017/09/20',
        },
        Category: 'JavaScript',
    },
    url: '/top-5-es6-features/'
};
 
var {title, Details: {date: {created, modified}}} = jsondata
console.log(title) // 'Top 5 JavaScript ES6 Features'
console.log(created) // '2017/09/19'
console.log(modified) // '2017/09/20'

分解陣列

對數組的解構作用類似於對象,除非在左邊使用方括號,而不是左邊的大括號:

1
2
3
4
var soccerteam = ['George', 'Dennis', 'Sandy']
var [a, b] = soccerteam // destructure soccerteam array
console.log(a) // "George"
console.log(b) // "Dennis"

在使用逗號(,)解壓其元素時,可以跳過某些數組元素:

1
2
3
4
var soccerteam = ['George', 'Dennis', 'Sandy']
var [a,,b] = soccerteam // destructure soccerteam array
console.log(a) // "George"
console.log(b) // "Sandy"

對我來說,析構消除了提取和分配對象屬性的所有摩擦,並以傳統的方式對數組進行了值處理。若要充分了解ES6破壞的複雜性和潛力,請閱讀“掌握ES6:破壞".

5)默認參數和REST參數

最後,我想提出的ES6接下來的兩個特性主要是處理函數參數。我們在JavaScript中創建的幾乎每個函數都接受用戶數據,因此這兩個特性肯定會在滿月時不止一次地派上用場。

默認參數

在使用應該具有默認值的參數創建函數時,我們都使用了以下模式:

1
2
3
4
5
function getarea(w,h){
var w = w || 10
var h = h || 15
return w * h
}

由於ES6對默認參數的支持,顯式定義參數值的測試結束了:

1
2
3
4
function getarea(w=10, h=15){
return w * h
}
getarea(5) // returns 75

更多關於ES6中默認參數的詳細信息這裏.

休息參數

ES6中的REST參數很容易將函數參數轉換爲數組,以便於操作。

1
2
3
4
5
function addit(...theNumbers){
    return theNumbers.reduce((prevnum, curnum) => prevnum + curnum, 0) // get the sum of the array elements
}
 
addit(1,2,3,4) // returns 10

通過在命名參數前面加上3個點(.),在該位置輸入到函數中的參數將自動轉換爲數組。

如果沒有REST參數,我們將不得不做一些像下面這樣複雜的事情手動將參數轉換爲數組第一:

1
2
3
4
5
6
function addit(theNumbers){
    var numArray = Array.prototype.slice.call(arguments) // force arguments object into array
    return numArray.reduce((prevnum, curnum) => prevnum + curnum, 0)
}
 
addit(1,2,3,4) // returns 10

REST參數僅可應用於函數參數的子集,如以下所示,它只將從第2段開始的參數轉換爲數組:

1
2
3
4
5
function f1(date, ...lucknumbers){
    return 'The Lucky Numbers for ' + date + ' are: ' + lucknumbers.join(', ')
}
 
alert( f1('2017/09/29', 3, 32, 43, 52) ) // alerts "The Lucky Numbers for 2017/09/29 are 3,32,43,52"

關於ES6中REST參數的完整規範,看這裏.

結語

你同意我的前5項ES6功能嗎?你最常使用的是哪一種?請分享以下評論。


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