1. 程式人生 > >ES6陣列的擴充套件--Array.from()和Array.of()

ES6陣列的擴充套件--Array.from()和Array.of()

小編推薦:Fundebug專注於JavaScript、微信小程式、微信小遊戲,Node.js和Java實時BUG監控。真的是一個很好用的bug監控費服務,眾多大佬公司都在使用。

一、 Array.from() : 將偽陣列物件或可遍歷物件轉換為真陣列

1.何為偽陣列

如果一個物件的所有鍵名都是正整數或零,並且有length屬性,那麼這個物件就很像陣列,語法上稱為“類似陣列的物件”(array-like object),即為偽陣列。

var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
obj[0] // 'a'
obj[1] // 'b'
obj.length // 3
obj.push('d') // TypeError: obj.push is not a function

上面程式碼中,物件obj就是一個類似陣列的物件。但是“類似陣列的物件”並不是陣列,因為它們不具備陣列特有的方法。物件obj沒有陣列的push方法,使用該方法就會報錯。

2.有哪些是偽陣列

典型的“類似陣列的物件”是函式的arguments物件,以及大多數 DOM 元素集,還有字串。

3.如何轉化為真陣列

①陣列的slice方法可以將“類似陣列的物件”變成真正的陣列

function doSomething(){
    console.log(arguments)
    var args = Array.prototype.slice.call(arguments);
    args.push("hj")
    console.log(args)
    return args
}
doSomething(1,2,3)

2922596973-5c2eb6dba79c6_articlex (578Ã256)

或者你也可以寫成:

function doSomething(){
    var args = [].slice.call(arguments);
    return args
}
doSomething(1,2,3)

儘管這種方法,也可以實現將類陣列轉變為陣列的目的,但並不直觀。ES6新增Array.from()方法來提供一種明確清晰的方式以解決這方面的需求,更推薦後者的辦法。

②Array.from()

<button>測試1</button>
<br>
<button>測試2</button>
<br>
<button>測試3</button>
<br>
<script type="text/javascript">
let btns = document.getElementsByTagName("button")
console.log("btns",btns);//得到一個偽陣列
//btns.forEach(item=>console.log(item)) Uncaught TypeError: btns.forEach is not a function
Array.from(btns).forEach(item=>console.log(item))將偽陣列轉換為陣列
</script>


3120892510-5c2eb6dba637b_articlex (570Ã172)

在ES6中,擴充套件運算子(...)也可以將某些資料結構轉為陣列。只不過它需要在背後呼叫遍歷器介面Symbol.iterator。值得注意的是如果一個物件沒有部署遍歷器介面,使用擴充套件運算子是無法將類似陣列物件轉換成陣列。

function doSomething (){ 
  return [...arguments] 
}
doSomething('a','b','c'); // ["a","b","c"]

4.Array.from()用法

Array.from接受三個引數,但只有input是必須的:

  • input: 你想要轉換的類似陣列物件和可遍歷物件
  • map: 類似於陣列的map方法,用來對每個元素進行處理,將處理後的值放入返回的陣列
  • context: 繫結map中用到的this

只要是部署了iterator介面的資料結構,Array.from都能將其轉為陣列:

let arr = Array.from('juejin'); 
console.log(arr); //["j", "u", "e", "j", "i", "n"]

Array.from還可以接受第二個引數,作用類似於陣列的map方法,用來對每個元素進行處理,處理後的值放入返回的陣列。

Array.from([1, 2, 3], (x) => x * x)// [1, 4, 9]
// 等同於
Array.from([1,2,3].map(x => x * x))

如果map函式裡面用到了this關鍵字,還可以傳入Array.from的第三個引數,用來繫結this。

Array.from()可以將各種值轉為真正的陣列,並且還提供map功能。這實際上意味著,只要有一個原始的資料結構,你就可以先對它的值進行處理,然後轉成規範的陣列結構,進而就可以使用數量眾多的陣列方法。

Array.from({ length: 2 }, () => 'jack')// ['jack', 'jack']

二、Array.of(v1, v2, v3) : 將一系列值轉換成陣列

當呼叫 new Array( )構造器時,根據傳入引數的型別與數量的不同,實際上會導致一些不同的結果, 例如:

let items = new Array(2) ;
console.log(items.length) ; // 2
console.log(items[0]) ; // undefined
console.log(items[1]) ;
let items = new Array(1, 2) ;
console.log(items.length) ; // 2
console.log(items[0]) ; // 1
console.log(items[1]) ; // 2

當使用單個數值引數來呼叫 Array 構造器時,陣列的長度屬性會被設定為該引數。 如果使用多個引數(無論是否為數值型別)來呼叫,這些引數也會成為目標陣列的項。陣列的這種行為既混亂又有風險,因為有時可能不會留意所傳引數的型別。

ES6 引入了Array.of( )方法來解決這個問題。該方法的作用非常類似Array構造器,但在使用單個數值引數的時候並不會導致特殊結果。Array.of( )方法總會建立一個包含所有傳入引數的陣列,而不管引數的數量與型別

let items = Array.of(1, 2);
console.log(items.length); // 2
console.log(items[0]); // 1
console.log(items[1]); // 2
items = Array.of(2);
console.log(items.length); // 1
console.log(items[0]); // 2

Array.of基本上可以用來替代Array()或newArray(),並且不存在由於引數不同而導致的過載,而且他們的行為非常統一。

參考文章

深入理解ES6

Javascript教程

JavaScript學習筆記:ES6陣列方法

關於Fundebug

Fundebug專注於JavaScript、微信小程式、微信小遊戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了9億+錯誤事件,得到了Google、360、金山軟體百姓網等眾多知名使用者的認可。歡迎免費試用!