使用js将伪数组转真数组

136 阅读2分钟

一、什么是真数组?

当一个对象具有以下特点时,可以称为数组:

  • 可以按照索引的方式,存储多个数组
  • 具有length属性,表示数组内数据的长度(个数)
  • 对象的原型属性__proto__,指向Array类,且可以使用Array的原型对象prototype身上的属性和方法,如:push,pop,shift,unshift等。

image.png

二、什么是伪数组?

  • 具有length(长度)属性;
  • 可以使用索引对数据进行操作;
  • 但是不能使用数组的方法,如push,pop等;
  • 因为伪数组具有长度和索引,所以可以使用循环语句遍历;
  • 就算给伪数组挂一个push方法,对应Array.prototype.push,但其constructor依然指向Object而不是Array,还是伪数组) image.png

三、注意区别

  1. 伪数组一般不会直接创建,而是通过一些js操作得到,如:document.getElementsByClassName()等;
  2. 并不是能使用部分数组的方法,就是称为真数组;
  3. 有些情况下,并不是将伪数组的原型__proto__属性设置为Array的原型对象prototype,就可以使用数组的方法

image.png

image.png

四、将伪数组转成真数组

如果在一些情况下,js给我们返回的是伪数组,但是我们想使用真数组的方法对之进行操作,那么此时就需要将伪数组转成真数组之后,才能继续使用。

接下来我们根据伪数组和真数组的区别和特点,对伪数组做一下改造,将伪数组转成真数组,以完成后续操作。

方法1:利用ES6提供的Array的from方法

var ali = document.getElementsByTagName('li');
console.log(ali);       // [li, li, li, li]
// ali.push("hello");      // TypeError: ali.push is not a function

var arr = Array.from(ali);

arr.push("hello");
console.log(arr);       // [li, li, li, li, "hello"]

方法2:遍历:创建一个空数组,循环遍历伪数组,将遍历出的数据逐一放在空数组中

var ali = document.getElementsByTagName('li');
console.log(ali);       // [li, li, li, li]
// ali.push("hello");      // TypeError: ali.push is not a function

var arr = [];           // 先创建空数组
for(var i=0;i<ali.length;i++){  // 循环遍历伪数组
    arr[i] = ali[i];    // 取出伪数组的数据,逐个放在真数组中
}

arr.push("hello");
console.log(arr);       // [li, li, li, li, "hello"]

方法3:利用原型的复制:将伪数组的__proto__复制为Array的prototype。但是这种方法有局限性

手动创建具有索引和长度的对象,作为伪数组

var obj = {
    0:"a",
    1:"b",
    2:"c",
    length:3
}
console.log(obj);       // {0: "a", 1: "b", 2: "c", length: 3}
// obj.push();          // TypeError: obj.push is not a function

obj.__proto__ = Array.prototype;

console.log(obj);       // ["a", "b", "c"]
obj.push("hello");
console.log(obj);       // ["a", "b", "c", "hello"]