其他分享
首页 > 其他分享> > js中伪数组转真数组

js中伪数组转真数组

作者:互联网

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

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

图1:真数组

二、什么是伪数组

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

图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"]
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");
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属性,且不能使用会改变原数组的方法。


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

标签:console,ali,li,数组,push,转真,中伪,hello
来源: https://blog.csdn.net/weixin_41636483/article/details/115082200