JavaScript里的数组Array使用方法总结,超全的o

試著忘記壹切 提交于 2020-03-07 03:26:51

一直以来都想来总结一下js的数组使用方法,因为有时候时间一长有的方法就记不太清,突然要用的时候还要去查,这里做下总结,自己巩固一下同时也方便以后有缘人一起来看😁

首先我们先来看一下谷歌浏览器里Array内置的方法有多少,如下↓

真是不看不知道,一看吓一跳,在我印象里数组的使用方法加上ES6新语法最多也就十几个吧

这里我数了一下从concat到valueOf总共37个(你敢信,无知啊),下面的“__”开头的就暂时不说了

----------------这里我们先来说一下最常用的几个,然后再一个一个解读剩下的----------------

1.Array.push()

-+-向数组的末尾添加一个或更多元素,并返回新的长度。

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

 

2.Array.pop()

-+-删除数组的最后一个元素,并返回删除的元素。

let arr = [1,2,3];
console.log(arr.pop());  // 3
console.log(arr)       // [1, 2]

 

3.Array.unshift()

-+-向数组的开头添加一个或更多元素,并返回新的长度。

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

 

4.Array.shift()

-+-删除并返回数组的第一个元素。

let arr = [1,2,3];
console.log(arr.shift()); // 1
console.log(arr)        // [2, 3]

 

 5.Array.splice(开始的位置下标,删除的个数,要插入的元素1,元素2,...)

-+-方法用于添加或删除数组中的元素,并返回删除的数组。PS:这个方法增删改查都可以,上面4个方法都可以用splice实现

let arr1 = ['a', 'b', 'c', 'd'];
console.log(arr1.splice(2,0,1));   // []
console.log(arr1)                  // ["a", "b", 1, "c", "d"]
let arr2 = ['a', 'b', 'c', 'd'];
console.log(arr2.splice(2,1));     // ['c']
console.log(arr2)                  // ["a", "b", "d"]
let arr3 = ['a', 'b', 'c', 'd']; 
console.log(arr3.splice(2,1,'e'));    // ["c"]
console.log(arr3);                    // ["a", "b", "e", "d"]
let arr4 = ['a', 'b', 'c', 'd']; 
console.log(arr4.splice(2,1,'e',4));  // ["c"]
console.log(arr4);                    // ["a", "b", "e", 4, "d"]

 

6.Array.slice(开始的位置下标,结束位置的下标)

-+-选取数组的的一部分,并返回一个新数组。(不包括结束位置)。注意:slice()方法不会改变原始数组。

其实slice()同样也可以操作字符串和substring()的功能一样

let arr1 = ['a', 'b', 'c', 'd'];
console.log(arr1.slice(1, 3));  // ["b", "c"]
console.log(arr1);              // ["a", "b", "c", "d"]
let arr2 = ['a', 'b', 'c', 'd'];
console.log(arr2.slice(1));     // ["b", "c", "d"]
console.log(arr2);              // ["a", "b", "c", "d"]

 

7.Array.concat(数组1,数组2,...)

-+-连接 2 个或更多数组,并返回连接后的新数组。注意:concat()方法不会改变原始数组。

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

 

8.Array.join(指定字符)

-+-将数组里所有的元素连接成一个字符串,并返回该字符串,元素是通过指定的分隔符进行分隔的。如果省略该参数,则使用逗号作为分隔符。

let arr = ["a", 1, "b", 2];
console.log(arr.join())     // "a,1,b,2"
console.log(arr.join("-"))  // "a-1-b-2"
console.log(arr)            // ["a", 1, "b", 2]

 

9.Array.toString()

-+-将数组作为字符串返回,数组中的元素之间用逗号分隔和arr.join()一个效果

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

 

10.Array.forEach(fn, thisValue)    thisValue可传可不传,决定在fn用this指向

-+-对数组中的每个元素运行给定函数。这个方法没有返回值。这里fn是可以传3个参数function(currentValue:必传当前元素, index:可选当前元素的索引值, arr:可选当前元素所属的数组对象)

let myArr = [1,5,8]
myArr.forEach((v,i,arr)=>{
  console.log(v,i,arr)
})
//1  0  [1, 5, 8]
//5  1  [1, 5, 8]
//8  2  [1, 5, 8]

加上thisValue看一下

本以为是应该把 newObj打印出来,没想到居然把window打印出来了,这是为什么呢,原来是ES6里的箭头函数this指向问题:作为方法的箭头函数this指向全局window对象

改成正常的匿名函数看一下

 这里要想使用thisValue还不能用箭头函数啊

 

11.Array.map()

-+-对数组中的每个元素运行给定函数,返回每次函数调用的结果组成的数组。

传参和forEach一样:Array.map(function(currentValue,index,arr), thisValue),唯一区分就是,map会返回每次函数调用的结果组成的数组

let myArr = [1,5,8]
myArr.forEach((v,i,arr)=>{
  console.log(v,i,arr)
})
//1  0  [1, 5, 8]
//5  1  [1, 5, 8]
//8  2  [1, 5, 8]
//[undefined, undefined, undefined] 在循环执行结束,把每次返回的undefined组成个数组返回了

 这里我们再来看一个动态图,更形象一点👇

 

12.Array.filter()

-+-对数组中的每个元素运行给定函数,返回该函数会返回 true 的元素组成的数组,传参和forEach一样:array.filter(function(currentValue,index,arr), thisValue)

let arr = [1, 2, 3, 4, 5]
let bigNum = value => value > 3
let newArr = arr.filter(bigNum)
console.log(newArr)
// [4, 5] 满足条件的元素返回为一个新的数组

  

13.Array.every()

-+-对数组中的每个元素运行给定函数,如果该函数对每个元素都返回 true ,则返回 true,就是检测数组中的每个元素是否都符合条件。传参和forEach一样array.every(function(currentValue,index,arr), thisValue)

let arr = [1, 2, 3, 4]
let isAllBig3 = value => value > 3
let isAllSmall8 = value => value < 8
console.log(arr.every(isAllBig3))      //false  不是所有都大于3
console.log(arr.every(isAllSmall8))    //true   是所有都小于8

  

14.Array.some()

-+-对数组中的每个元素运行给定函数,如果任一元素返回 true ,则返回 true,如果返回了true , 循环结束,剩余的元素不会再执行检测。传参和forEach一样:array.some(function(currentValue,index,arr),thisValue)

let arr= [1, 2, 3]
let ishave3 = value => value == 3
let ishave6 = value => value == 6
console.log(arr.some(ishave3))    // true  arr里有3
console.log(arr.some(ishave6))    // false arr里没有6

  

15.Array.reduce()

-+-将数组元素计算为一个值(从左到右)。array.reduce(function(total, currentValue, currentIndex, arr), initialValue)

total:初始值是数组第一个值,后面会赋值为每次循环返回的值

currentValue:初始值是数组第二个值,后面依次第三个...到最后一个

注意:该方法只循环arr.length-1

所以我们通常用它来计算一个数组元素之和

let arr = [1, 2, 3, 4]
let add = (a, b) => a + b
console.log(arr.reduce(add))  //   10

  

16.Array.reduceRight()

-+-将数组元素计算为一个值(从右到左)。和上面的方法功能一样,只是循环正好相反从最后一个元素开始

 

17.Array.sort()

-+-如果不传参数按照字母顺序对数组排序(默认排序顺序是根据字符串UniCode码),支持传入指定排序方法的函数作为参数:arr.sort(fn(secondValue, firstValue))

先看最简单的用法:

let arr = ["dfc", "cf", "lol", "anf"]
console.log(arr.sort());         //   ["anf", "cf", "dfc", "lol"]
console.log(arr)                 //   ["anf", "cf", "dfc", "lol"]
该方法会改变原始数组

其实sort底层是封装了排序算法的,V8 引擎 sort 函数只给出了两种排序 InsertionSort 和 QuickSort,数量小于10的数组使用 InsertionSort,比10大的数组则使用 QuickSort点击githubV8-Arrray.js源码地址

底层源码有兴趣的童鞋可以去研究研究,下面我们来看一下如何利用sort()的排序来给我们平时项目开发带来便利:

  • 方法一:a-b 升序排列
    let arr = [4, 2, 3, 6, 9, 1]
    console.log(arr.sort((a, b)=> a-b))
    // [1, 2, 3, 4, 6, 9]  
  • 方法二:b-a 降序排列
    let arr = [4, 2, 3, 6, 9, 1]
    console.log(arr.sort((a, b)=> b-a))
    // [9, 6, 4, 3, 2, 1]
  • 方法三:对于复杂的数据数组,我们可以封装属于自己排序方法
    let students = [
        {name: "tom", age: 18},
        {name: "jack", age: 26},
        {name: "rose", age: 20}
    ]
    let sortByAge = (a, b) => a.age - b.age
    students.sort(sortByAge)
    /* 最后输出
    [{name: "tom", age: 18},
     {name: "rose", age: 20},
     {name: "jack", age: 26}]
    */
  • 方法四:其实我们还可以写的再灵活一点,更低耦合点
    // 先想一下如果还有学生身高数据,要我们按身高来进行排序,如果按上面那种写法
    // 我们得封装两个方法,如果以后还有更多的属性,这样是不是很麻烦
    // 看下面↓
    let students = [
        {name: "tom", age: 18, height: 177},
        {name: "jack", age: 26, height: 170},
        {name: "rose", age: 20, height: 166}
    ]
    let sortBy = (attr) => {return (a, b)=> a[attr] - b[attr]}
    students.sort(sortBy("height"))
    /*输出
    0: {name: "rose", age: 20, height: 166}
    1: {name: "jack", age: 26, height: 170}
    2: {name: "tom", age: 18, height: 177}
    */
    students.sort(sortBy("age"))
    /*输出
    0: {name: "tom", age: 18, height: 177}
    1: {name: "rose", age: 20, height: 166}
    2: {name: "jack", age: 26, height: 170}
    */
    

      

18.Array.reverse()

-+-反转数组的元素顺序。会改变原始数组

let arr = [11, 12, 14, 13]
console.log(arr.reverse())   // [13, 14, 12, 11]
console.log(arr)             // [13, 14, 12, 11]

  

19.Array.find()

-+-对数组中的每个元素运行给定函数,在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。如果没有符合条件的元素返回 undefined

传参:array.find(function(currentValue, index, arr),thisValue)

let arr = [1, 2, 3, 5, 7]
let big3 = a => a>3
console.log(arr.find(big3))  // 5
console.log(arr)             // [1, 2, 3, 5, 7]

 

20.Array.findIndex()

-+-返回符合传入测试(函数)条件的数组元素索引。之后的值不会再调用执行函数。如果没有符合条件的元素返回 -1

let arr = [1, 2, 3, 5, 7]
let big3 = a => a>3
console.log(arr.findIndex(big3))  // 3
console.log(arr)                  // [1, 2, 3, 5, 7]

 

21.Array.includes()

-+-判断一个数组是否包含一个指定的值。如果是返回 true,否则false。语法:arr.includes(searchElement, fromIndex)

[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true

  

22.Array.indexOf()

-+-返回第一个与给定参数相等的数组元素的索引,没有找到则返回 -1。语法:array.indexOf(item,start),start选填:从下标这(包括该元素)之后的所有元素

let arr = ["aa", "bb", "cc", "dd"]
console.log(arr.indexOf("bb"))       // 1
console.log(arr.indexOf("bb", 2))    // -1

  

23.Array.lastIndexOf()

-+-返回在数组中搜索到的与给定参数相等的元素的索引里最大的值,没有找到返回-1。语法:array.lastIndexOf(item,Index),index选填:指下标在这(包括该元素)之前的所有元素

let arr = ["aa", "bb", "cc", "dd", "bb"]
console.log(arr.lastIndexOf("bb"))      // 4
console.log(arr.lastIndexOf("bb", 2))   // 1

  

24.Array.isArray()

-+- 判断对象是否为数组。如果对象是数组返回 true,否则返回 false。

let obj = {}
let arr = []
Array.isArray(obj)  // false
Array.isArray(arr)  // true

  

25.Array.valueOf()

 -+-返回数组对象的原始值。

let arr = [1,2,3]
console.log(arr.valueOf())
//  [1, 2, 3]

  

26.Array.entries()、27.Array.keys()、28.Array.values() 

-+-ES6 提供三个新的方法: entries() , keys() 和 values() 用于遍历数组。它们都返回一个遍历器对象,可以用 for...of 循环进行遍历,唯一的区别是 keys() 是对键名的遍历、 values() 是对键值的遍历, entries() 是对键值对的遍历。

let arr = ["a", "b", "c"]
let item = arr.entries()
console.log(item.next().value)  // [0, "a"]
console.log(item.next().value)  // [1, "b"]
console.log(item.next().value)  // [2, "c"]
console.log(item.next().value)  // undefined

let ikey = arr.keys()
console.log(ikey.next().value)  // 0
console.log(ikey.next().value)  // 1
console.log(ikey.next().value)  // 2
console.log(ikey.next().value)  // undefined

let ivalue = arr.values()
console.log(ivalue.next().value)  // a
console.log(ivalue.next().value)  // b
console.log(ivalue.next().value)  // c
console.log(ivalue.next().value)  // undefined

  

29.Array.flat(num)

-+-用于将嵌套的数组“拉平”,变成一维数组。该方法返回一个新数组,对原数组没有影响。num:表示拉几层的嵌套数组,如果不确定可以写Infinity,这样不管多少层都可以

[1, 2, [3, 4]].flat()            // [1, 2, 3, 4]
[1, 2, [3, [4, 5]]].flat()     // [1, 2, 3, [4, 5]]
[1, 2, [3, [4, 5]]].flat(2)   // [1, 2, 3, 4, 5]
[1, [2, [3]]].flat(Infinity)  // [1, 2, 3]
// 如果原数组有空位,flat()方法会跳过空位。
[1, 2, , 4, 5].flat()           // [1, 2, 4, 5]

 

30.Array.flatMap()

-+-对原数组的每个成员执行一个函数,相当于执行map(),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。

[2, 3, 4].flatMap((x) => [x, x * 2])  // [2, 4, 3, 6, 4, 8]

  

31.Array.fill()

-+-用于将一个固定值替换数组的元素,语法:array.fill(value, start, end)

let arr = ["a", "b", "c", "d", "e"]
arr.fill("dd")
console.log(arr)  //  ["dd", "dd", "dd", "dd", "dd"]
arr.fill("a", 1, 3)
console.log(arr)  //  ["dd", "a", "a", "dd", "dd"]

  

32.Array.copyWithin()

-+- 从数组的指定位置拷贝元素到数组的另一个指定位置中。语法:array.copyWithin(target, start, end)

target:必需。复制到指定目标索引位置。
start:可选。元素复制的起始位置。
end:可选。停止复制的索引位置 (默认为 array.length)。如果为负值,表示倒数。

let arr = ["a", "b", "c", "d", "e", "f"];
arr.copyWithin(2, 0, 2);
console.log(arr)
// ["a", "b", "a", "b", "e", "f"]

 

33.Array.toLocaleString()

-+-这方法数组基本不用了,主要操作日期对象返回一个日期,该日期使用当前区域设置并已被转换为字符串。

let arr = ["a", "b", "c"]
arr.toLocaleString()
//  返回空
["a", "b", "c"].toLocaleString()
// "a,b,c"
new Date().toLocaleString()
// "2020/3/7 上午12:26:31"

  

34.Array.constructor

 -+-返回对象的构造函数。

[1,2,3].constructor
// Array() { [native code] }

  

35.Array.hasOwnProperty()、36.Array.propertyIsEnumerable()、37.Array.isPrototypeOf()

这三个方法都是和原型链相关的,操作数组基本用不到

  • hasOwnProperty()
    let arr = ["a", "b"]
    arr.hasOwnProperty("a")
    // false
    arr.hasOwnProperty("0")
    // true
  • 其实hasOwnProperty主要是返回一个布尔值,判断对象是否包含特定的自身(非继承)属性。看下面↓
    function f(){
      this.a = 1;
      this.b = 2;
      this.c = function(){}
    }
    f.prototype = {
      d : 3,
      e : 4,
      g : function(){}
    }
    let o = new f();
    o.hasOwnProperty('a'); //true
    o.hasOwnProperty('b'); //true
    o.hasOwnProperty('c'); //true
    o.hasOwnProperty('d'); //false
    o.hasOwnProperty('e'); //false
    o.hasOwnProperty('g'); //false
    
    o.propertyIsEnumerable('a'); //true
    o.propertyIsEnumerable('b'); //true
    o.propertyIsEnumerable('c'); //true
    o.propertyIsEnumerable('d'); //false
    o.propertyIsEnumerable('e'); //false
    o.propertyIsEnumerable('g'); //false
  • propertyIsEnumerable()是用来检测属性是否属于某个对象的,如果检测到了,返回true,否则返回false. 
  • 1.这个属性必须属于实例的,并且不属于原型. 

    2.这个属性必须是可枚举的,也就是自定义的属性,可以通过for..in循环出来的. 

    只要符合上面两个要求,就会返回true; 

    let arr = ["a", "b", "c"]
    arr.propertyIsEnumerable("a")
    // false
    arr.propertyIsEnumerable("0")
    // true
  • isPrototypeOf()用于测试一个对象是否存在于另一个对象的原型链上。数组基本用不到

到这里开始图片里的37个方法我们都试验了一遍

------------------------------good-------------------------------

另外补充ES6 还新增了 Array.of() 与 Array.from() 方法 

38.Array.of()

-+-of是帮助开发者在使用 Array 构造器时避开 JS 语言的一个怪异点。调用 new Array() 构造器时,根据传入参数的类型与数量的不同,实际上会导致一些不同的结果

let items = new Array(2);
console.log(items.length); // 2
console.log(items[0]); // undefined
console.log(items[1]); // undefined

items = new Array("2");
console.log(items.length); // 1
console.log(items[0]); // "2"

items = new Array(1, 2);
console.log(items.length); // 2
console.log(items[0]); // 1
console.log(items[1]); // 2

items = new Array(3, "2");
console.log(items.length); // 2
console.log(items[0]); // 3
console.log(items[1]); // "2"

这时候引入了 Array.of() 方法来解决这个问题。该方法的作用非常类似 Array 构造器,但在使用单个数值参数的时候并不会导致特殊结果。 Array.of() 方法总会创建一个包含所有传入参数的数组,而不管参数的数量与类型。

let items = Array.of(1, 2);
console.log(items.length); // 2
console.log(items[0]); // 1
console.log(items[1]); // 2

items = Array.of(2);
console.log(items.length); // 1
console.log(items[0]); // 2

items = Array.of("2");
console.log(items.length); // 1
console.log(items[0]); // "2"

 

39Array.form()

-+-form()方法用于通过拥有 length 属性的对象或可迭代的对象来返回一个数组。如果对象是数组返回 true,否则返回 false。

Array.from("abcdef");
// ["a", "b", "c", "d", "e", "f"]

 

 

---------------------结尾总结---------------------------

都是些简单方法总结我居然写了一天,如有错误的地方望大家及时指正😂

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!