js中伪数组转真数组

本文详细介绍了JavaScript中的真数组和伪数组的概念,以及如何通过不同方法将伪数组转换为真数组,包括遍历、slice、Array.from、展开运算符以及修改原型。此外,还探讨了在某些情况下,即使修改了原型,仍无法直接使用数组方法的原因,并提供了相应解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

图1:真数组

二、什么是伪数组

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

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

图2:伪数组

注意:

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

图3:依然是伪数组

  1. 有些情况下,并不是将伪数组的原型__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伪数组化为数组有多种方法。其中一种方法是通过遍历伪数组,将遍历出的数据逐一放入一个新的空数组中。首先,创建一个空数组。然后,使用循环遍历伪数组,将每个元素逐个存入新数组中。最后,可以在新数组中使用数组的方法。例如,可以使用以下代码实现: ```javascript var pseudoArray = document.getElementsByTagName('li'); // 伪数组 var newArray = []; // 新建空数组 for (var i = 0; i < pseudoArray.length; i++) { newArray[i = pseudoArray[i]; // 将伪数组的元素逐个存入新数组 } console.log(newArray); // 新数组,即数组 ``` 通过以上方法,我们可以将JS伪数组化为数组。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [js伪数组变成数组的六种方法](https://blog.youkuaiyun.com/qq_44803640/article/details/115111173)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [js伪数组数组](https://blog.youkuaiyun.com/weixin_41636483/article/details/115082200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨树林er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值