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
复制代码
相关文章
相关标签/搜索