1、展開操作符
顧名思義,用於對象或數組之前的展開操作符(…),將一個結構展開爲列表。
如下:
let firstHalf = [ one , two ];
let secondHalf = [ three , four , ...firstHalf];
這樣寫比較簡潔、優雅,如果不用展開操作符,我們需要這樣做:
let firstHalf = [ one , two ];
let secondHalf = [ three , four ];
for(var i=0, i <firstHalf.length; i++ ) {
secondHalf.push(firstHalf[i]);
}
展開操作符也適用於合併對象的屬性:
const hero = {
name: 'Galen',
realName: ‘蓋倫’
}
const heroDetail = {
...hero,
age: 18
}
2、剩餘參數
剩餘參數將剩餘的參數收入數列。JavaScript 的特性是參數數目很靈活。通常會有一個 arguments
變量收集參數。
如下:
function add(first, second, ...remaining) {
return first + second;
}
上面代碼只能返回first和second的和,即使傳入更多參數,效果也一樣:調用:add(1, 2)和調用:add(1,2,3,4)效果一樣
修改一下:
function add(first, second, ...remaining) {
return first + second + remaining.reduce((acc, curr) => acc + curr, 0);
}
…remaining 收集了剩餘的參數,爲我們提供了這些參數的命名,清楚地表明我們打算處理剩餘的參數。
3、字符串插值
當我們定義一個Class
類的時候,可能會這麼寫:
class Product {
constructor(name, description, price) {
this.name = name;
this.description = description;
this.price = price;
}
getDescription() {
return " Full description:" +
" name: " + this.name +
" description: " + this.description
}
}
其中的getDescription()
方法可讀性不佳,變量和字符串拼接,不夠簡潔。
有了字符串插值,我們可以改寫getDescription()
方法如下:
getDescription() {
return `Full description: name: ${this.name} description: ${this.description}`
}
這樣要拼接的字符串裏可以用${}
插值,方便了很多。
4、屬性和方法屬性簡寫
在之前,即使屬性的屬性名和屬性值是一樣的,也必須這麼寫:
var name = 'kevin'
var age = 18
var obj = {
name: name,
age: age,
action: function () {
//do something...
}
}
使用了ES6後,當屬性的屬性名和屬性值是一樣的時候,可以這麼簡寫:
var name = 'kevin'
var age = 18
var obj = {
name,
age,
action () {
//do something...
}
}
5、解構賦值
場景:當我們需要從一個請求中獲取結果,並進行賦值時,可能會寫這樣的代碼:
function handle(req, res) {
// 獲取結果
const name = req.body.name;
const description = req.body.description;
const url = req.url;
console.log( name, description , url);
// 賦值操作
dbService.createPerson(name, description)
}
當使用解構賦值的時候,上面代碼就可以簡化爲:
function handle(req, res) {
const { body: { name, description }, url } = req;
console.log( name, description , url);
dbService.createPerson(name, description)
解構賦值並不僅僅侷限於對象。它同樣適用於數組。
考慮下面的代碼:
const array = [1,2,3,4,5,6];
const a = array[0];
const c = array[2];
上面的代碼可以改寫爲:
const array = [1,2,3,4,5,6];
const [a, ,c, ...remaining] = arr;
// remaining = [4,5,6]
我們可以使用上面的模式匹配分解數組的值。我們使用 , , 跳過某些值。上面提到過的剩餘參數這裏也能用,在這裏我們通過剩餘參數捕獲了剩餘的數組成員。
解構賦值還可以用於函數和參數。函數有不止 2-3 個參數時,使用一個對象收集所有參數是 JavaScript 的事實標準。
例如,下面一個函數:
function doSomething(config) {
if(config.a) { ... }
if(config.b) { ... }
if(config.c) { ... }
}
有更好的寫法:
function doSomething({ a, b, c }) {
if(a) { ... }
if(b) { ... }
if(c) { ... }
}
6、數組方法
ES6 引入了許多有用的數組方法,例如:
find()
,查找列表中的成員,返回 null 表示沒找到findIndex()
,查找列表成員的索引some()
,檢查某個斷言是否至少在列表的一個成員上爲真includes
,列表是否包含某項
如下代碼理解其用法
const array = [{ id: 1, checked: true }, { id: 2 }];
arr.find(item => item.id === 2) // { id: 2 }
arr.findIndex(item => item.id === 2) // 1
arr.some(item => item.checked) // true
const numberArray = [1,2,3,4];
numberArray.includes(2) // true
Promises + Async/Await
(還有不少好用的數組方法,有待發掘)
7、異步方案
這個是針對層層嵌套的回調函數,像之前我們會寫出這樣的代碼:
function doSomething(cb) {
setTimeout(() => {
cb( done )
}, 3000)
}
doSomething((arg) => {
console.log( done here , arg);
})
我們使用回調是因爲有些操作是異步的,需要時間來完成。後來我們有了 promise 庫,人們開始使用它。然後 JavaScript 逐漸加入了對 promise 的原生支持。
function doSomething() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve( done )
}, 3000)
})
}
doSomething().then(arg => {
console.log( done here , arg);
})
我們甚至可以這樣調用,將 promise 串起來:
getUser()
.then(getOrderByUser)
.then(getOrderItemsByOrder)
.then(orderItems => {
// 處理排序後的成員
})
而是用async
和await
,讓我們以同步編程的方式解決這些異步問題:
async function getItems() {
try {
const user = await getUser();
const order = await getOrderByUser(user);
const items = await getOrderItemsByOrder(order);
return items;
} catch(err) {
// 在這裏處理錯誤,建議返回某個值或者重新拋出錯誤
}
}
getItems().then(items => {
// 處理排序後的成員
}
關於async/await
更詳細的內容,看我的另一篇博客:async和await(點擊即可查看)
8、模塊
差不多任何編程語言都支持模塊這一概念,也就是將代碼分爲多個文件,每個文件是一個自我包含的單元(模塊)。
// math.js
export function add(a,b) { return a + b; }
export function sub(a,b) { return a - b; }
export default mult(a,b) => a * b;
// main.js
import mult, { add, sub } from ./math ;
mult(2, 4) // 8
add(1,1) // 2
sub(1,2) // -1
我們在上面用 export 關鍵字註明了 add 和 sub 這兩個結構對任何引入該模塊的模塊都公開可見。export default 關鍵字則註明僅僅 import 模塊時得到的結構。在 main.js 中,我們將導入的 default 命名爲 mult,同時指明我們引入 add() 和 sub() 這兩個方法。
注: 本文參考自公衆號:前端工匠, 其作者:浪裏行舟