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)
或者你也可以寫成:
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>
在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(),並且不存在由於引數不同而導致的過載,而且他們的行為非常統一。
參考文章
關於Fundebug
Fundebug專注於JavaScript、微信小程式、微信小遊戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了9億+錯誤事件,得到了Google、360、金山軟體、百姓網等眾多知名使用者的認可。歡迎免費試用!