JS中類數組中那些事兒

引言

JavaScript函數具有像數組同樣的對象,這些對象稱爲arguments,與傳遞給函數的參數相對應。傳遞給JavaScript函數的全部參數均可以使用arguments對象來引用。數組

arguments是數組嗎?

要回答這個問題首先了解一下argument的具體知識。bash

函數中的arguments對象

語法: argumentsapp

描述 arguments對象是全部函數(非箭頭)中均可用的局部變量。可使用arguments對象在函數中引用函數的參數。此對象包含傳遞給函數的每一個參數的條目,第一個條目的索引從0開始。函數

argument[0];
argument[1];
複製代碼

也能夠設置其參數:ui

arguments[1]='new value';
複製代碼

事實上,arguments對象不是一個Array。相似於一個數組,可是除了length屬性和索引元素以外沒有任何Array屬性。this

什麼時候調用arguments?

若是調用的參數多於正式聲明接受的參數,則可使用arguments對象。這種技術對於能夠傳遞可變數量的參數的函數頗有用。使用 arguments.length來肯定傳遞給函數參數的個數,而後使用arguments對象來處理每一個參數。spa

屬性

arguments.callee:指向當前執行的函數。prototype

arguments.caller:指向調用當前函數的函數。3d

arguments.length:指向傳遞給當前函數的參數數量。code

arguments[@@iterator]:返回一個新的Array迭代器對象,該對象包含參數中每一個索引的值。

注意: 如今在嚴格模式下,arguments對象已與過往不一樣。arguments[@@iterator]再也不與函數的實際形參之間共享,同時caller屬性也被移除。

例子

遍歷參數求和

function add(){
    var sum=0;
    var len=arguments.length;
    for(var i=0;i<len;i++){
        sum+=arguments[i];
    }
    return sum;
}
add();          //-> 0
add(1);         //-> 1
add(1,2,3,4);   //-> 10
複製代碼

定義鏈接字符串的函數

這個例子定義了一個函數來鏈接字符串。這個函數惟一正式聲明瞭的參數是一個字符串,該參數指定一個字符做爲銜接點來鏈接字符串。該函數定義以下:

function myConcat(separator){
    var args=Array.prototype.slice.call(arguments,1);
    return args.join(separator);
}
myConcat(",","red","orange","blue");    //->  "red,orange,blue"
myConcat("; ", "elephant", "giraffe", "lion", "cheetah");    //-> "elephant; giraffe; lion; cheetah"
複製代碼

綜上,arguments不是一個數組,而是一個類數組

類數組及轉換成數組的方法

什麼是類數組?

類數組,顧名思義,相似於一個數組,可是它是一個對象:是至關於一個對象,裏面有數組的值以及相應的屬性-length。

  • 擁有length屬性,其屬性(索引)爲非負整數
  • 不具備數組所具備的方法
var likeArray={
    0:"a",
    1:"第二"
    2:"3"
    'length':3,        //重點在這!沒有length屬性就不是類數組。
    splice:Array.prototype.slice,
    splice:Array.prototype.splice
}
likeArray.push(2);  //雖然此時likeArray由於splice方法將{}變成了[],而且有length屬性
//可是其繼承的原型仍是Object,還不能調用push(),會報錯!
複製代碼

JS中常見類數組對象

NameNodeMap

Dom元素用過attributes屬性獲取NameNodeMap對象:

var div=document.getElementById('div');
var nameNodeMap=div.attribute;
複製代碼

這是NameNodeMap的結構:

HTMLCollection 經過DOM元素的children屬性獲取元素的子元素集合,即HTMLCollection集合對象

NodeList 經過DOM元素的childNodes屬性返回包含被選節點的子節點的NodeList

類數組轉換成數組的方法

  • Array.prototype.slice.call(likeArray): 利用slice的返回新數組以及call改變this指向而造成一個新數組
  • Array.from(likeArray):ES6的新方法
  • [...likeArray],或者在函數傳值時用..."收集"; //...要求likeArray是有Symbol的iterator屬性
var obj = {
    'a':1,
    'length':5,
},
//方法一:
arr = Array.prototype.slice.call(obj),    //-> [empty * 5]

//方法二:
arr1 = Array.from(obj);    //-> [undefined,undefined,undefined,undefined,undefined]

//方法三(ES6展開運算符):
var arr2=[...obj]  //報錯,由於obj無Symbol的iterator屬性
var set = new Set([1,2,3]);   //set有Symbol的iterator屬性
console.log([...set]);   //[1,2,3]

//方法四(利用concat):
function sum(a, b) {
  let args = Array.prototype.concat.apply([], arguments);//apply方法會把第二個參數展開
  console.log(args.reduce((sum, cur) => sum + cur));//args能夠調用數組原生的方法啦
}
sum(1, 2);//3
複製代碼
相關文章
相關標籤/搜索