美文网首页码农
js中伪数组转真数组

js中伪数组转真数组

作者: 潜水的旱鸭子 | 来源:发表于2019-10-14 15:22 被阅读0次

一、什么是真数组(数组)

所谓真数组,其实可以直接称为:数组。
当一个对象具有以下特点时,可以称为数组:

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

二、什么是伪数组

所谓伪数组,当一个对象具有以下特点:

  • 具有length(长度)属性;
  • 可以使用索引对数据进行操作;
  • 但是不能使用数组的方法,如push,pop等。如图2:
图2:伪数组

注意:
1.伪数组一般不会直接创建,而是通过一些js操作得到,如:document.getElementsByName()等;
2.因为伪数组具有长度和索引,所以可以使用循环语句遍历;
3.并不是能使用部分数组的方法,就是称为真数组;如图3:

图3:依然是伪数组

4.有些情况下,并不是将伪数组的原型__proto__属性设置为Array的原型对象prototype,就可以使用数组的方法。如图4:

图4:还是伪数组

三、如何将伪数组转成真数组

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

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

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

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"]

方法2:使用slice方法:利用Array原型对象的slice方法,配合apply,将slice中的this指向伪数组

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.prototype.slice.apply(ali);

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

方法3:利用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"]

方法4:利用ES6提供的展开运算符(...)

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

var arr = [...ali];

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

方法5:利用原型的复制:将伪数组的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"]
  • arguments也适用
function fn(){
    var arg = arguments;
    console.log(arg);       // ["a", "b", ...]
    // arg.push("hello");   // TypeError: arg.push is not a function

    arg.__proto__ = Array.prototype;

    arg.push("hello");
    console.log(arg);       // ["a", "b", "hello", ...]
}
fn("a","b");
  • 选择器返回的元素集合不适用,因为就算将元素集合的原型改成了数组原型(如图5),但元素集合本身是只读的,依然不能修改
var ali = document.getElementsByTagName('li');
console.log(ali);            // [li, li, li, li]
// ali.push("hello");        // TypeError: ali.push is not a function

ali.__proto__ = Array.prototype;

// ali.push("hello");        // Index property setter is not supported
图5

但是不是意味着,没有修改到原数组的方法就可以使用呢(注意图5,没有length属性)

ali.forEach(val => {
    console.log(val);
});

// 会发现浏览器没执行,原因是此时ali缺少length或length为0
console.log(ali.length);    // 0

需要提前获取ali的length,在修改原型之后再手动设置

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

var len = ali.length;        // 获取初始length
ali.__proto__ = Array.prototype;
ali.length = len;            // 设置给修改原型之后的数组对象

// ali.push("hello");        // Index property setter is not supported
ali.forEach(val => {
    console.log(val);        // 遍历打印数组中的值
});
console.log(ali.length);     // 4

小提示:选择器返回的元素数组,使用复制原型方法,还需要手动设置length属性,且不能使用会改变原数组的方法。


以上。
关于伪数组转真数组的方法或技巧,后期继续补充...
文中如果纰漏,错误,不合理,描述不清晰,不准确等问题,欢迎大家留言指正...

相关文章

  • js中伪数组转真数组

    一、什么是真数组(数组) 所谓真数组,其实可以直接称为:数组。当一个对象具有以下特点时,可以称为数组: 可以按照索...

  • call,apply,bind的实际应用

    call,apply,bind详解传送门 求数组中的最大和最小值 将伪数组转化为数组 js中的伪数组(例如通过do...

  • JS 将伪数组转换成数组 🎄

    本文简介 点赞 + 关注 + 收藏 = 学会了 在 JS 中,伪数组 是非常常见的,它也叫 类数组。伪数组可能会给...

  • JS 将伪数组转换成数组

    本文简介 点赞 + 关注 + 收藏 = 学会了 在 JS 中,伪数组 是非常常见的,它也叫 类数组。伪数组可能会给...

  • 2019前端经典面试题

    1.简述对标签语义化的理解。 2. css实现垂直水平居中 3. js中哪些是伪数组?如何将伪数组转化为标准数组?...

  • 伪数组

    1、伪数组特点 2、常见伪数组 3、伪数组与数组的区别 4、伪数组转成真数组

  • js中的数组和伪数组

  • 在javascript中什么是伪数组?如何将伪数组转换为标准数组

    伪数组?一听到这个词懵了,知道js中有数组,竟然还有伪数组?在面试过程中,面试官问的有些东西我们不是不会,而是被专...

  • js伪数组

    伪数组是一个含有length属性的json对象,它是按照索引的方式存储数据,它并不具有数组的一些方法. 1. 将伪...

  • 关于javascript中的伪数组

    1、什么是js伪数组? 请看下面一段代码: 控制台输出: 上图就是一个伪数组,长相很像数组,但是将他的原型 _pr...

网友评论

    本文标题:js中伪数组转真数组

    本文链接:https://www.haomeiwen.com/subject/wqeopctx.html