JavaScript基础之数组下篇---伪数组以及应用案例

上一篇聊了一些JavaScript中数组的基础,现在可以更加深入的了解一些关于数组的知识,以及前面聊function的时候说arguments是一个伪数组的问题。

本篇主要是根据上一篇的方法,用自己的方式去还原一些数据的操作方法,更好的理解数组的本质。

本篇更是侧重于对前面聊的伪数据的进一步的了解。

伪数组

伪数组对比数组

其实说起伪数组前面前面聊过 ,毕竟function中的arguments就是一种伪数组。但是没有进一步的进行详细聊,到底伪数组的原理是什么,以及伪数组的进一步的应用。现在开始聊这个。不过还是老规矩,先上代码,后面聊。

function test(){
    console.log(arguments);
    
}
test(1,2,3,4,5);
var arr=[1,2,3,4,5];
console.log(arr);

对比着看两者打印出的内容。

在这里插入图片描述

发现其__proto__一个指向的是Array一个是Object;

手动创建伪数组

当然彼此都有各自的length属性。所以可以看出虽然相似但又不是同一个类型的东西。自然手动也可以创建一个伪数组

var arr1={
    0:1,
    1:2,
    2:3,
    3:4,
    4:5,
    length:5
}

在这里插入图片描述

当然自己创建的没有带有

  • symbol(Symbol.iterator): 这个是为迭代而服务的。
  • callee: ,当前arguments对象是在输入哪个函数的参数对象。(前有一个小篇说过此属性值)

伪数组的神奇操作

这个时候又有可以操作的神奇方式了,那就是将我们创建的伪数组打印的时候像是一个数组,这个涉及到一个神奇的数组属性方法,

var arr2={
    0:1,
    1:2,
    2:3,
    3:4,
    4:5,
    length:5,
    splice:Array.prototype.splice
}

在这里插入图片描述

可以看出__proto__的属性值还是Object但是打印的却不是一对{ }而一对[]。神奇不?

既然可以这样,那么是否可以进一步将类似push的方法也放进去,然后看是否可以调用呢?

var arr3={
    0:1,
    1:2,
    2:3,
    3:4,
    4:5,
    length:5,
    splice:Array.prototype.splice,
    push:Array.prototype.push,
}
arr3.push(6);

在这里插入图片描述

其实push本身就是一个简单方法,自己也可以实现

// 这个好好理解一下,因为下面例题中需要对这个方法逻辑了解
function mypush(v){
    this[this.length]=v;
    this.length++;
}

在这里插入图片描述

经典例题

现在来一个神奇的例题来了解,以及补充小伪数组上面漏掉的东西。

var arr4={
    2:3,
    3:4,
    length:2,
    splice:Array.prototype.splice,
    push:Array.prototype.push,
}
arr4.push(1);
arr4.push(2);
console.log(arr4);
//现在不看下面,大胆的猜测一下其打印出的内容是什么?

在这里插入图片描述

为什么会出现这样的情况?

首先打印push前的伪数组。

在这里插入图片描述

可以看出属性的key用数字表示 如果splice:Array.prototype.splice那就会变成数组的下标值,如果前数组后面不会补充但是前面定然会补充的,再做一个实验:

var arr4={
    1:3,
    3:4,
    length:2,
    splice:Array.prototype.splice,
    push:Array.prototype.push,
}

在这里插入图片描述

为啥只有一个空呢?因为splice:Array.prototype.splice有了数组的性质,其length=2会直接将其截断,而后面的3:4又因为其本身是key-value对,所以优先权比较高,而空却只是数组属性而补充的而已。

很简单证明,直接length=3试试。

var arr4={
    1:3,
    3:4,
    length:3,
    splice:Array.prototype.splice,
}

在这里插入图片描述

上面的明白的话,可以再搞一个实验,如果将key值变成字母呢?

var arr4={
    a:3,
    b:4,
    length:2,
    splice:Array.prototype.splice,
    push:Array.prototype.push,
}
arr4.push(1);
arr4.push(2);
console.log(arr4);

在这里插入图片描述

可见splice:Array.prototype.splice有了数组的性质,会影响key值为数字的,其它的就无法体现出数组性质的属性来了。

然后for循环得到其key

for(key in arr4){
    console.log(key);
}

在这里插入图片描述

可见如果通过数组属性补充的位置,不是不算是key值。

如果看一下key的类型呢?

for(key in arr4){
    console.log(typeof key);
}

在这里插入图片描述

可见是7个字符串,可见哪怕写的属性值为数字,本质还是String

这个时候又有大胆想法了

//既然无法同.数字得到那变成字符串呢?
arr4.'2';

在这里插入图片描述

arr4[2];//和数组取值有点像只能

在这里插入图片描述

如果其它key为非数字呢?

arr4.a;
arr4["a"];

在这里插入图片描述

伪数组转换成真正数组

这个需要神奇的一个Array.prototype.slice

当然也不是像是打印出数组的样子用:Array.prototype.splice

var arr4={
    2:3,
    3:4,
    length:2,
    slice:Array.prototype.slice,
    push:Array.prototype.push,
}

在这里插入图片描述

而是这样操作:

var arr4={
    2:3,
    3:4,
    length:4
}
arr5=Array.prototype.slice.call(arr4);

在这里插入图片描述

应用

其实前面说了那样多,无论如何说其根本还是有什么用呢?

例子1

1: 如果将方法的参数放在一个数组中当然不是放在后面,如果那样话就太简单了,比如 arr =[1,2,3],参数是"a","b","c" 最后arr为["a","b","c",1,2,3],记住一点参数是不固定。

方法1:

var arr=[1,2,3]
function test(){
    for (i=0;i<arguments.length;i++){
        arr.splice(i,0,arguments[i])
    }
}

在这里插入图片描述

方法2:

var arr=[1,2,3]
function test(){
        arr=Array.prototype.slice.call(arguments).concat(arr);
}

在这里插入图片描述

例子2

var arr=[2,4,5,6,5,0,0,"a","b","a"]
定义一个原型方法:将数组中的元素去重.

//直接将元素作为key和value,方便我们判断。
Array.prototype.uni=function(){
    
    
    var newobj={
    
    };
    var newarr=[];
   for(i=0;i<this.length;i++){
    
    
       //if(!newobj[this[i]]) 这样不行,因为有的元素值是0,0再布尔值隐式转换的时候有问题不会将0完全去重
       if(!newobj.hasOwnProperty(this[i])){
    
    
           newobj[this[i]]=this[i];
           newarr.push(this[i])
       }
   }
    return newarr;
}



var arr=[2,4,5,6,5,0,0,"a","b","a"];
arr.uni();

在这里插入图片描述

例子3

写一个方法,输入数字然后返回星期几

方法1:

function test(num){
  switch (num){
    case 0:
         console.log("Sunday");
        break;
    case 1:
         console.log("Monday");
        break;
    case 2:
         console.log("Tuesday");
        break;
    case 3:
         console.log("Wednesday");
        break;
    case 4:
         console.log("Thursday");
        break;
    case 5:
         console.log("Friday");
        break;
    case 6:
         console.log("Saturday");
        break;
    default:
         console.log("输入错误");
        break;
    }
}

方法2

function test(num){
    var arr=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
    if(arr[num]){
        console.log(arr[num]);
    }else{
         console.log("输入错误");
    }
}
或者

function test(num){
    var arr=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
   
    arr[num] ? console.log(arr[num]):console.log("输入错误");
  
}

猜你喜欢

转载自blog.csdn.net/u011863822/article/details/121639957