Javascript中的的类数组

185 阅读1分钟

类数组

定义:js里存在一些类似数组能通过索引获取值并且具有length属性但又不是真数组的称为类数组(array-like)

因为它并不是真数组,所以不具备数组的方法。

Nodelist对象

DOM元素列表就是类数组:

<ul class="box1">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>
let lis = document.querySelectorAll("li");
lis.forEach(() => {
  console.log(1);
});//输出5次1
lis.map(() => {
  console.log(1);
});//报错

他不是类数组吗?为什么能用forEach不能用map?

因为document.querySelectorAll返回一个NodeList对象,这个对象上有forEach方法、item(更具数字返回对应的节点)、和三个返回迭代器的方法(keys、values、entries).所以他能也仅能用foeEach遍历。

还有一个NodeList对象:Node.childNodes,

这两个有什么区别? childNodes实时的,document.querySelectorAll是静态的。

let lis = document.querySelectorAll("li");
var parent = document.querySelector(".box1");
var child = parent.childNodes;

//childNodes会包含空文本节点,所以是11
console.log(child.length);//11
console.log(lis.length);//5
//添加一个子节点
let li = document.createElement("li");
parent.append(li);

console.log(child.length);//12
console.log(lis.length);//5

详情见[MDN](NodeList - Web API 接口参考 | MDN (mozilla.org))

转化为真数组

可以借用数组的slice方法或者直接使用Array.from() 将类数组转化为数组。

建议使用Array.from()方法进行转化,方便。

Array.prototype.slice.call(lis).map((item) => {
  console.log(1);       //输出五次1
});
Array.from(lis).filter((item) => {
  console.log(2);				//输出五次2
});

argument对象(es6不再推荐)

function fn(q, d, f) {
  //下面这段代码会报错;
  arguments.forEach(() => {
    console.log(1);
  });

  Array.from(arguments).forEach(() => {
    console.log(1); //输出五次1
  });
}
fn(1, 2, 3, 4, 5);
function fn2(...rest) {
  rest.forEach(() => {
    console.log(1); //输出五次1
  });
}
fn2(1, 2, 3, 4, 5);

第二段代码使用rest语法会更好,也是es6推荐的。