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属性 | 无 | 有 |