【相關推薦:、】
ES6的擴充套件運運算元,它的語法很簡單,使用三個點號表示「...」。可以將一個陣列轉為用逗號分隔的引數序列。
它將可迭代物件展開到其單獨的元素中,所謂的可迭代物件就是任何能用 for of
迴圈進行遍歷的物件,例如:陣列、字串、Map
、Set
、DOM
節點等。
var array = [1,2,3,4]; console.log(...array);//1 2 3 4 var str = "String"; console.log(...str);//S t r i n g
function push(array, ...items) { array.push(...items); } function add(x, y) { return x + y; } const numbers = [4, 38]; add(...numbers) // 42
上面程式碼中,array.push(...items)
和add(...numbers)
這兩行,都是函數的呼叫,它們都使用了擴充套件運運算元。該運運算元將一個陣列,變為引數序列。
const arr = [ ...(x > 0 ? ['a'] : []), 'b', ];
如果擴充套件運運算元後面是一個空陣列,則不產生任何效果。
[...[], 1] // [1]
擴充套件運運算元還有許多用法...
const m = Math.max(1, 2, 3); //結果為3
但如果要計算陣列裡的最大值,顯然陣列是不能直接作為 Math.max() 的引數,我們需要把它展開。在ES6之前,我們也是需要結合apply來處理:
var arr = [2, 4, 8, 6, 0]; function max(arr) { return Math.max.apply(null, arr); } console.log(max(arr));
ES6使用擴充套件運運算元(...)就很簡單就可以展開,上面的例子變為:
var arr = [2, 4, 8, 6, 0]; console.log(Math.max(...arr)); // 3
擴充套件運運算元給了我們全新的合併陣列的方法
// ES5 apply 寫法 var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; Array.prototype.push.apply(arr1, arr2); //arr1 [0, 1, 2, 3, 4, 5]
使用擴充套件運運算元就可以很簡單地把陣列展開為參數列
const a1 = [{ foo: 1 }]; const a2 = [{ bar: 2 }]; const a3 = a1.concat(a2); const a4 = [...a1, ...a2]; a3[0] === a1[0] // true a4[0] === a1[0] // true
上面程式碼中,a3
和a4
是用兩種不同方法合併而成的新陣列,但是它們的成員都是對原陣列成員的參照,這就是淺拷貝。如果修改了參照指向的值,會同步反映到新陣列。
注意:這兩種方法都是淺拷貝,使用的時候需要注意。
陣列是複合的資料型別,直接複製的話,只是複製了指向底層資料結構的指標,而不是克隆一個全新的陣列。
ES5 只能用變通方法來複制陣列。
const a1 = [1, 2]; const a2 = a1.concat(); a2[0] = 2; a1 // [1, 2]
上面程式碼中,a1
會返回原陣列的克隆,再修改a2
就不會對a1
產生影響。
擴充套件運運算元提供了複製陣列的簡便寫法。
//拷貝陣列 var array0 = [1,2,3]; var array1 = [...array0]; console.log(array1);//[1, 2, 3] //拷貝陣列 var obj = { age:1, name:"lis", arr:{ a1:[1,2] } } var obj2 = {...obj}; console.log(obj2);//{age: 1, name: "lis", arr: {…}}
記住:陣列仍通過指標得到,所以我們並沒有複製陣列本身,我們複製的只是一個新的指標。
NodeList
物件是節點的集合,通常是由屬性,如Node.childNodes
和方法,如document.querySelectorAll
返回的。
像 NodeList 和 arguments 這種偽陣列,類似於陣列,但不是陣列,沒有 Array
的所有方法,例如find
、map
、filter
等,但是可以使用 forEach()
來迭代
可以通過擴充套件運運算元將其轉為陣列,如下:
const nodeList = document.querySelectorAll(".row"); const nodeArray = [...nodeList]; console.log(nodeList); console.log(nodeArray);
注意:使用擴充套件運運算元將偽陣列轉換為陣列有侷限性,這個類陣列必須得有預設的迭代器且偽可遍歷的
擴充套件運運算元可以與解構賦值結合起來,用於生成陣列
// ES5 a = list[0], rest = list.slice(1) // ES6 [a, ...rest] = list
下面是另外一些例子:
const [first, ...rest] = [1, 2, 3, 4, 5]; first // 1 rest // [2, 3, 4, 5] const [first, ...rest] = []; first // undefined rest // [] const [first, ...rest] = ["foo"]; first // "foo" rest // []
注意:如果將擴充套件運運算元用於陣列賦值,只能放在引數的最後一位,否則會報錯。
const [...butLast, last] = [1, 2, 3, 4, 5]; // 報錯 const [first, ...middle, last] = [1, 2, 3, 4, 5]; // 報錯
ES6的擴充套件語法可以很簡單的把一個字串分割為單獨字元的陣列:
[...'hello'] // [ "h", "e", "l", "l", "o" ]
擴充套件運運算元內部呼叫的是資料結構的 Iterator 介面,因此只要具有 Iterator 介面的物件,都可以使用擴充套件運運算元,比如 Map 結構。
let map = new Map([ [1, 'one'], [2, 'two'], [3, 'three'], ]); let arr = [...map.keys()]; // [1, 2, 3]
Generator 函數執行後,返回一個遍歷器物件,因此也可以使用擴充套件運運算元。
var go = function*(){ yield 1; yield 2; yield 3; }; [...go()] // [1, 2, 3]
上面程式碼中,變數go
是一個 Generator 函數,執行後返回的是一個遍歷器物件,對這個遍歷器物件執行擴充套件運運算元,就會將內部遍歷得到的值,轉為一個陣列。
如果對沒有 Iterator 介面的物件,使用擴充套件運運算元,將會報錯。
const obj = {a: 1, b: 2}; let arr = [...obj]; // TypeError: Cannot spread non-iterable object
【相關推薦:、】
以上就是一起來聊聊ES6中的擴充套件運運算元的詳細內容,更多請關注TW511.COM其它相關文章!