Array.from
方法主要用於將Array-Like Obj
(包括DOM對象document.querySeletorAll(...)
)和iterable
對象轉化爲數組。和下面說的spread
操做符相比,它能夠直接將Array-Like obj
進行轉化,而不須要這個類數組對象是iterable
的。javascript
function add() { let arr = [].slice.apply(arguments); } function add() { let arr = Array.from(arguments); } -------- //經過這個方法,將`Array-Like Obj`直接轉化爲了Array.所以可使用Array提供的方法 var lis = Array.from(document.querySelectorAll('li')); lis.forEach(function(dom, index) { // do something });
此外,Array.from
還接收第二個參數,和Array.prototype.map
方法相似.java
function foo() { let args = Array.from(arguments, item => item + 1); console.log(args); } foo(1, 2, 3); // 2 3 4
能夠利用Array.from
來返回字符串的長度,由於在js
裏面,大於uFFFF的Unicode
字符長度是算爲2個的。es6
//這裏是由於String類型的數據是iterable的,因此能夠被Array.from轉化爲數組 function countLen(str) { return Array.from(str).length; }
rest
參數主要是在定義函數的時候,用以獲取函數多餘的函數,這樣在函數內部便可不使用arguments
對象.由於rest
參數是一個數組,所以能夠直接利用Array
提供的相應的API。數組
好比一個求和的函數: 之前的寫法: function add() { [].reduce.call(arguments, function(x, y) { return x + y; }); } es6: function add(...args) { args.reduce((x, y) => x + y); }
還可使用rest
參數搭配解構賦值
使用:數據結構
function foo(...args) { let [x = 0, y = 2] = args; //.... }
在使用箭頭函數的時候:app
function foo(...args1) { var obj = { add: () => { console.log(arguments); } } obj.add(1, 2, 3); } foo(4, 5, 6); //最後輸出 [4, 5, 6]
這裏由於箭頭函數沒有自身的this
,它內部的this
事實上是由所在的做用域提供的。所以arguments
對象也是所在做用域提供的。因此會輸出[4, 5, 6]
。dom
這裏若是要正確獲取obj.add(1, 2, 3)
提供的參數,可使用rest
參數:函數
function foo(...args1) { var obj = { add: (...args2) => { console.log(args2); } } obj.add(1, 2, 3); } foo(4, 5, 6); //最後輸出 [1, 2, 3]
spread
操做符用以將一個iterable
(部署了[Symbol.Iterator]接口)的value
轉化爲用逗號分隔的參數序列。this
哪些數據結構部署了[Symbol.Iterator]
的接口呢:prototype
Array
Maps
Sets
部署了[Symbol.Iterator]
接口的Array-like obj
(arguments)
Dom data Structures
String
對象字面量:
var obj = { name: 'xl', age: 20 } console.log(...obj);
是沒有部署[Symbol.Iterator]
接口的,所以使用spread
操做符時會報錯:
Uncaught TypeError: (var)[Symbol.iterator] is not a function(…)
同時,普通的Array-like
的Obj
:
var obj = { 0: 'x', 1: 'l', length: 2 }
一樣使用spread
操做符時會報錯。若是將這個Array-like
的Obj
轉化爲Array
,則須要手動在這個obj
上配置[Symbol.iterator]
接口:
var obj = { *[Symbol.iterator]() { yield 'x'; yield 'l' } } console.log(...obj); // x l
或者換用其餘的API:
方式1: let arr1 = Array.from(obj); 方式2: let arr1 = [].slice.apply(obj);
像以前計算一組數當中最大的數:
Math.max.apply(null, [1, 2, 3]); --->>> Math.max(...[1, 2, 3]); // 3
此外,spread
操做符還能將部署了[Symbol.Iterator]
接口的類數組對象轉爲用逗號分隔的參數序列:
var li = document.querySeletorAll('li'); [...li]; //轉化爲數組後就能夠利用數組提供的API進行其餘的操做
上面屢次提到了iterable
或者是部署了[Symbol.iterable]
方法的value
,事實上它們說的都是同一個意思,一個話去歸納的話就是: iterable
的數據結構提供了統一的接口供外部去獲取自身的元素。它所提供的這個接口方法名稱就是[Symbol.iterator]
.
上文已經提到了哪些數據結構部署了[Symbol.Iterator]
的接口。
哪些方法會調用[Symbol.Iterator]
接口呢:
解構賦值
let [a, b] = [1, 2];
for...of
循環
for(let value of [1, 2]) { }
spread
操做符
[...document.querySelectorAll('li')]
Promise.all()/Promise.race()
Promise.all(iterableOverPromises).then(···); Promise.race(iterableOverPromises).then(···);
yield*
yield* anIterable
關於iterable
和iterator
單獨用一篇文章來寫吧。