JS中存在类数组对象,不能直接调用数组的方法,但是又和数组类似。

哪些是类数组?

  • 函数里面的参数对象 arguments
  • 用 getElementsByTagName/ClassName/Name 获得的 HTMLCollection
  • 用 querySelector 获得的 NodeList

问题1:

类数组是否能使用数组的方法呢?

问题2:

类数组有哪些方法可以转换为数组?

arguments

在日常开发中经常会遇到各种类数组对象,最常见的便是在函数中使用的 arguments

function foo(name, age, sex) {
    console.log(arguments);
    console.log(typeof arguments);
    console.log(Object.prototype.toString.call(arguments));
}
foo('jack', '18', 'male');
function foo(name, age, sex) {
    console.log(arguments.callee);  // 返回自身p
}
foo('jack', '18', 'male');

HTMLCollection

HTMLCollection简单来说是HTML DOM对象的一个接口,这个接口包含了获取到的DOM元素集合,返回的类型是类数组对象

如果用typeof来判断的话,它返回的是’object’

它是及时更新的,当文档中的DOM变化时,它也会随之变化

var elem1,elem2;
// document.forms 是一个 HTMLCollection
elem1 = document.forms[0];
elem2 = document.forms.item(0);
console.log(elem1);
console.log(elem2);
console.log(typeof elem1);
console.log(Object.prototype.toString.call(elem1));

NodeList

NodeList对象是节点的集合,通常是由querySelector返回的

NodeList可以使用for……of来迭代,在一些情况下,NodeList是一个实时集合

var list = document.querySelectorAll('input[type=checkbox]');

for(var checkbox of list) {
    checkbox.checked = true;
}

console.log(list);
console.log(typeof list);
console.log(Object.prototype.toString.call(list));

类数组应用场景

遍历参数操作

在函数内部可以直接获取arguments这个类数组的值,那么也可以对于参数进行一些操作

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

定义链接字符串函数

function myConcat(separa) {
    var args = Array.prototype.slice.call(arguments,1);
    return args.join(separa);
}

myConcat(',','red','orange','blue');
// 'red,orange,blue'

myConcat(';','elephant','lion','snake');
// 'elephant;lion;snake'

myConcat('.','one','two','three','four','five');
// 'one.two.three.four.five'

传递参数使用

如果在结合arguments,还能实现什么?

可以借助arguments将参数从一个函数传递到另一个函数

// 使用apply将foo的参数传递给bar
function foo() {
    bar.apply(this,arguments);
}
function bar(a,b,c) {
    console.log(a,b,c);
}
foo(1,2,3); // 1 2 3

类数组如何转换成数组

类数组借用数组方法转数组

var arrayLike = {
    0: 'java',
    1: 'script',
    length: 2
}

Array.prototype.push.call(arrayLike,'jack','lily');
console.log(typeof arrayLike); // 'object'
console.log(arrayLike);
// {0:'java',1:'script',2:'jack',3:'lily',length:4}
function sum(a,b) {
    let args = Array.prototype.slice.call(arguments);
    // let args = [].slice.call(arguments); // 这样写也是一样的效果
    console.log(args.reduce((sum,cur) => sum + cur));
}
sum(1,2); // 3

function sum(a,b) {
    let args = Array.prototype.concat.apply([],arguments);
    console.log(args.reduce((sum,cur) => sum + cur));
}
sum(1,2); // 3

ES6的方法转数组

采用ES6新增的Array.from方法,以及展开运算符的方法

function sum(a,b) {
    let args = Array.from(arguments);
    // let args = [].slice.call(arguments); // 这样写也是一样的效果
    console.log(args.reduce((sum,cur) => sum + cur));
}
sum(1,2); // 3

function sum(a,b) {
    let args = [...arguments];
    console.log(args.reduce((sum,cur) => sum + cur));
}
sum(1,2); // 3

function sum(...args) {
    console.log(args.reduce((sum,cur) => sum + cur));
}
sum(1,2); // 3

总结

方法/特征 数组 类数组
自带方法 多个方法
length属性
callee属性