写在前面

数组作为一个最基础的一维数据结构,在各种编程语言中充当着至关重要的角色,不深入了解数组,就不足以写好Javascript。随着React和Vue等MVVM框架的流行,数据更新的同时视图也会随之更新。开发者会用数组来进行数据的存储和各种增删改查等操作,从而实现对应前端视图层的更新。截止es7规范,数组总共包含33个标准api方法和一个非标准的api方法。

那么:

  • 数组的构造器有哪几种?
  • 哪些是改变自身值的方法?
  • 哪些不是改变自身值的方法?
  • 遍历方法有哪些?

Array构造器

Array构造器用于创建一个新的数组,通常推荐使用对象字面量的方式创建数组,但是也有对象字面量创建数组乏力的时候。比如说创建一个长度为6的空数组,使用字面量形式是无法实现的。

  1. //使用Array构造器,可以自定义长度
  2. const arr = Array(6);//[empty × 6]
  3. //使用对象字面量形式
  4. const arr1 = [];
  5. arr1.length = 6;//6

new Array(arg1,arg2,...)参数长度为0或长度>=2时,传入的参数将按照顺序依次成为新数组的0至N项(参数为0时,返回空数组)。

new Array(len)当len不是数值时,处理如上所示,返回一个只包含len元素一项的数组;当len是数值时,len最大不能超过32位无符号整型,即需要小于2的32次方,否则将会抛出异常RangError。

  1. const arr1 = new Array();//[]
  2. const arr2 = new Array(18);//[empty × 18]
  3. const arr3 = new Array("yichuan","onechuan");//["yichuan","onechuan"]
  4. const arr4 = new Array("yichuan");//["yichuan"]
  5. const arr5 = new Array(2020,2021);//[2020, 2021]

es6新增的构造方法:Array.of和Array.from。其中Array.of用的少些,Array.from更具有灵活性。

Array.of()

Array.of用于将参数依次转为数组中的一项,然后返回这个新数组,而不论这个参数是数字还是其它。

Array.of() 和 Array 构造函数之间的区别在于处理整数参数:Array.of(7) 创建一个具有单个元素 7 的数组,而 Array(7) 创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

  1. Array.of(7); // [7]
  2. Array.of(1, 2, 3); // [1, 2, 3]
  3. Array(7); // [ , , , , , , ]
  4. Array(1, 2, 3); // [1, 2, 3]

Array.from()

Array.from()的设计初衷是快速便捷地基于其它对象创建新数组,准确而言就是从一个类数组的可迭代对象中,创建一个新的数组实例。Array.from() 方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

  1. Array.from(arrayLike[, mapFn[, thisArg]])

Array.from()可以输入三个参数:

  • 类数组或可迭代对象,必选参数
  • 加工函数,新生成的数组将会经过此函数的加工而返回,可选参数
  • this的作用域,表示加工函数执行时的this指向的对象,可选参数 ```javascript const obj = { 0:”yichuan”, 1:”onechuan”, 2:”pingchuan”, length:3 }

Array.from(obj,function(value,index){ console.log(value,index,this,arguments.length); return value.repeat(3);//必须指定返回值,否则为undefined },obj)

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/22745085/1638698994238-3e8bdb35-0f59-46b4-a1a9-807acdf0c4c6.png#clientId=u4670c6fc-e471-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=29&id=ua4db5514&margin=%5Bobject%20Object%5D&name=image.png&originHeight=58&originWidth=1484&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18790&status=done&style=none&taskId=ub1aa84d4-a06a-4bbe-a1df-a43486ff873&title=&width=742)<br />当不需要改变this的指向的话,可以将加工函数写成箭头函数形式。
  2. ```javascript
  3. //string
  4. Array.from("yichuan");//["y","i","c","h","u","a","n"]
  5. //Set
  6. Array.from(new Set(["yichuan","onechuan"]));//["yichuan","onechuan"]
  7. //Map
  8. Array.from(new Map([[1,"yichuan"],[2,"onechuan"]]));//[[1,"yichuan"],[2,"onechuan"]]

Array.isArray()

Array.isArray()是用来判断一个变量是否为数组类型的方法。这样用于进行数组判断的方法就有6种:

  • 基于instanceof
  • 基于constructor
  • 基于Object.prototype.isPrototypeOf
  • 基于getPrototypeOf
  • 基于Object.prototype.toString
  • 基于Array.isArray()

    1. const arr = [];
    2. //1.基于instanceof
    3. console.log(arr instanceof Array);
    4. //2.基于constructor
    5. console.log(arr.construcot === Array);
    6. //3.基于Object.prototype.isPrototypeOf
    7. console.log(Array.prototype.isPrototypeOf(arr));
    8. //4.基于getPrototypeOf
    9. console.log(Object.getPrototypeOf(arr) === Array.prototype);
    10. //5.基于Object.prototype.toString
    11. console.log(Object.prototype.toString.call(arr)==="[object Array]");
    12. //6.基于Array.isArray()
    13. console.log(Array.isArray(arr));

    可以优化下数组判断:

    1. if(!Array.isArray){
    2. Array.isArray = function(arg){
    3. return Object.prototype.toString.call(arg) === "[object Array]";
    4. }
    5. }

    数组

    在Javascript中数组api根据是否改变自身的方法有:

  • 改变自身的方法:pop、push、reverse、shift、sort、splice、unshift以及两个es6新增的方法copyWithin和fill


  • 改变自身的方法

    (1) Array.prototype.pop()

    pop()从数组中删除最后一个元素,并返回该元素的值。此方法更改数组的长度。pop()可以和call()或apply()一起使用时,可应用在类似数组的对象上。

    1. const arr = ["red","green","blue"];
    2. console.log(arr.pop());//"blue"

    (2) Array.prototype.push()

    push() 方法将一个或多个元素添加到数组的末尾,并返回该数组的新长度。push()可以和call()或apply()一起使用时,可应用在类似数组的对象上。

    1. const arr = ["red","green","blue"];
    2. console.log(arr.push("black"));//4

    (3) Array.prototype.reverse()

    reverse() 方法将数组中元素的位置颠倒,并返回该数组。数组的第一个元素会变成最后一个,数组的最后一个元素变成第一个。该方法会改变原数组,返回该数组的引用。

    1. const arr = ["red","green","blue"];
    2. console.log(arr.reverse());//["blue","green","red"]

    (4) Array.prototype.shift()

    shift() 方法从数组中删除第一个元素,并返回该元素的值。此方法更改数组的长度。

    1. const arr = ["red","green","blue"];
    2. console.log(arr.shift());//"red"

    (5) Array.prototype.sort()

    sort()方法使用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。无法保证排序的时间和空间复杂性。默认是从小到大排序。

    1. const arr = [89,70,22,11,333];
    2. console.log(arr.sort(arr));//[11,22,70,89,333]

    当然,我们也可以对sort的函数sortFun()进行自定义对数组排序:

  • sortFun(a, b)<0,表示a可以排在b前;

  • sortFun(a, b)=0,表示a和b的位置不变;
  • sortFun(a, b)>0,表示a排在b后

sortFun()总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

  1. const arr = [89,70,22,11,333];
  2. console.log(arr.sort((x,y)=>x>y));//[333,89,70,22,11]

(6) Array.prototype.splice()

splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

  1. array.splice(startIndex,deleteCount,[item1,item2,...]);

Array.prototype.splice()可以输入三个参数:

  • startIndex:指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n);如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
  • deleteCount:整数,表示要移除的数组元素的个数。
    • deleteCount>startIndex之后元素的总数,则从startIndex开始后面的元素都将被删除(包含startIndex位)
    • 如果deleteCount被省略了,或者它的值大于等于array.length - start(也就是说,如果它大于或者等于start之后的所有元素的数量),那么start之后数组的所有元素都会被删除。
    • 如果 deleteCount <=0,则不移除元素。这种情况下,至少应添加一个新元素。
  • [item1,item2,…]:是可选参数,要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。 ```javascript //删除指定索引后的元素 const arr = [“red”,”green”,”blue”]; console.log(arr.splice(2));//[“red”,”green”]

//要向数组中添加的元素 const arr = [“red”,”green”,”blue”]; console.log(arr.splice(1,[“black”,”brown”]));//[“red”,”black”,”brown”,”green”,”blue”]

  1. <a name="lxTvm"></a>
  2. #### (7) Array.prototype.unshift()
  3. unshift() 方法将一个或多个元素添加到数组的开头,并返回该数组的新长度(该方法修改原有数组)。unshift 方法会在调用它的类数组对象的开始位置插入给定的参数。
  4. ```javascript
  5. arr.unshift(element1, ..., elementN)

使用:

  1. let arr = [4,5,6];
  2. arr.unshift(1,2,3);
  3. console.log(arr); // [1, 2, 3, 4, 5, 6]

(8) Array.prototype.copyWithin()

copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。

  1. arr.copyWithin(targetIndex, startIndex, endIndex);

arr.copyWithin()可以输入三个参数:

  • targetIndex:0 为基底的索引,复制序列到该位置。
    • 如果是负数,targetIndex 将从末尾开始计算。
    • 如果 targetIndex >= arr.length,将会不发生拷贝。
    • 如果 targetIndex > startIndex,复制的序列将被修改以符合 arr.length。
  • startIndex:0 为基底的索引,开始复制元素的起始位置。
    • 如果是负数,startIndex将从末尾开始计算。
    • 如果 startIndex 被忽略,copyWithin 将会从0开始复制。
  • endIndex:0 为基底的索引,开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。
    • 如果是负数, end 将从末尾开始计算。
    • 如果 end 被忽略,copyWithin 方法将会一直复制至数组结尾(默认为 arr.length)。