盘点数组所有方法(一)

519 阅读12分钟

Array对象本身的方法

1, Array.from()

语法:Array.from(arrayLike[, mapFn[, thisArg]])

其作用本身就是把一个类数组转换成一个真的数组,比如我们通过document.querySelectorAll获取到的元素组合,就可以通过Array.from转换成为一个真正的数组,从而直接进行操作。

案例:

  let list = document.querySelectorAll('li');
  Array.from(list).forEach((item,index)=>{
      item.onclick = function(){
          console.log(index);
      }
  })

结果:

在这里插入图片描述

参数:

  • arrayLike,字面意思,简单粗暴,像数组的东西(有下标有length) 比如元素列表,字符串等等
  let str = 'ahsda';
  Array.from(str).forEach((item)=>{
      console.log(item);//a,h,s,d,a
  });
  • mapFn,其实就相当于数组的map方法,直接把每一项都执行此函数,方便对数组中的每一项进行一些操作,不需要在Array.from的后面加一个forEach了
  let str = 'ahsda';
  let reg = Array.from(str,(item)=>{
      return item + '1';
  });
  console.log(reg);//["a1", "h1", "s1", "d1", "a1"]
  • thisArg 这个参数其实是依存于第二个参数,用于指定执行第二个参数中的函数时,函数里面的this指向; 当然,这个情况下第二个参数就不能再使用箭头函数了,箭头函数的this指向问题前面已经提到过了,有兴趣可以看看这篇文章

  • 一些骚操作:

1,把字符串拆成数组

  Array.from('foo'); 
  // [ "f", "o", "o" ]

2,生成指定长度的数组

  Array.from({length: 5}, (v, i) => i);
  // [0, 1, 2, 3, 4]

2,Array.isArray()

这个方法其实很简单粗暴,就是用来去判断参数是不是一个数组,这里列出来一些判断案例:

  // 下面的函数调用都返回 true
  Array.isArray([]);
  Array.isArray([1]);
  Array.isArray(new Array());
  Array.isArray(new Array('a', 'b', 'c', 'd'))
  // 鲜为人知的事实:其实 Array.prototype 也是一个数组。
  Array.isArray(Array.prototype); 

  // 下面的函数调用都返回 false
  Array.isArray();
  Array.isArray({});
  Array.isArray(null);
  Array.isArray(undefined);
  Array.isArray(17);
  Array.isArray('Array');
  Array.isArray(true);
  Array.isArray(false);
  Array.isArray(new Uint8Array(32))
  Array.isArray({ __proto__: Array.prototype });

源代码其实也非常简单:

  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };

这么简单,直接get ! 在这里插入图片描述

3,Array.of()

这个方法就更简单了,可以传入若干个参数,这个方法会返回一个数组,参数就是数组中的每一项,它和Array本身有点类似,看案例:

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

那么它和Array不同的点在于,如果只传入一个数字,Array得到的是一个空数组,这个数字就是数组的长度,而Array.of得到的仍然是一个数组,这个数字会存放在数组中:

  Array.of(7); // [7] 
  Array(7);    // [ , , , , , , ]

Array.prototype上的方法

1,concat()

语法:let new_array = old_array.concat(value1[, valueN]);

这个方法相信大家都很熟悉了,没什么可说的,就是连接几个数组,拼成一个新的数组。看下面的案例:

案例:

  let obj = {
      a:1233
  };
  let arr = [obj,1,2,3];
  let arr2 = [4,5,6];

  let arr3 = arr.concat(arr2,7,8,9);
  console.log(arr3);//[{…}, 1, 2, 3, 4, 5, 6, 7, 8, 9]

注意:

结果大家都已经看到了,contact方法里可以传入若干个参数,如果传入的是数组,那么就会把数组展开,不过只展开一层, 也就是说如果是二维数组,那么拼接得到的也会是二维数组

然后参数不一定都是数组,可以是其他的值,但是要注意的是 如果是值类型,那么将会复制值类型到新的数组中,如果是引用类型,引用类型将会被浅拷贝

这也就是我为什么要在数组中放一个obj的原因,arr3中也会包含obj这个对象,但是他们的引用地址是一样的,也就是说obj发生改变的时候,arr3中的对象也会发生改变。

2,entries()

语法:arr.entries()

这是ES6新增的数组遍历方法,数组调用entries方法会返回一个迭代器:Iterator音标:[ɪtə'reɪtə],这个对象里面包含了数组的下标和对应的值 ps:其实发音很简单,直接把单词拆开就好了,i ter ra tor

  let arr2 = [4,5,6];
  let ite = arr2.entries();
  //ite 就是得到的迭代器,它身上有一个next方法

得到的迭代器对象里有一个方法next, 这个方法调用之后可以得到一个对象,

  console.log(ite.next())

对象里有两个属性:

  {
    done: false
    value: [0, 4]
  }

done,表示遍历是否完成,迭代器itenext方法每调用一遍,就会重新得到一个对象,done的值也会跟着改变,比如上面只调用了一遍,而数组的有三个值,显然是还没有遍历完成的,所以done的值是false,如果说ite.next()执行3次,那么done的值就会变成true.

value,表示当前这次遍历得到的值,上面只调用了一次,所以得到的是[0,4],要注意的是0代表下标,4代表对应的值,如果ite.next()再调用一次的话,得到的value应该就是[1,5],以此类推

注意

如果你想一次性得到所有的下标和值的键值对,可以使用 for...of方法遍历迭代器:

  let arr2 = [4,5,6];
  let ite = arr2.entries();
  for(item of ite){
      console.log(item);
  }

  //[0, 4]
  //[1, 5]
  //[2, 6]

3,every()

语法:arr.every(callback(element, index, array)[, thisArg])

every方法是ES6推出的比较经典的方法之一了,和some方法是组合CP。

every方法用于判定数组中的值是否符合回调函数中的条件,如果每一个值都符合,那么every方法则返回true,如果其中一项不符合,则直接返回false,并且不再遍历后续其他值。这也比较符合every这个词的意思:每一个都要符合

some就不一样了,只要其中一项符合,则返回true,如果全都不符合,才会返回false。

案例:

判断数组中的数字是否大于10,如果全都大于10,则every方法返回true。一旦其中有一项不符合要求,则会返回 false

  function isBigEnough(element, index, array) {
    return element >= 10;
  }
  [12, 5, 8, 130, 44].every(isBigEnough);   // false
  [12, 54, 18, 130, 44].every(isBigEnough); // true

4,some()

every方法里已经讲到了,它和every方法是一对 some方法测试数组中是不是至少有1个元素通过了被提供的函数测试。它返回的是一个Boolean类型的值。

不过有特殊情况:如果用一个空数组进行测试,在任何情况下它返回的都是false。

语法:arr.every(callback(element, index, array)[, thisArg])

案例:配合箭头函数的话写起来会更简洁

  [2, 5, 8, 1, 4].some(x => x > 10);  // false
  [12, 5, 8, 1, 4].some(x => x > 10); // true

5,fill()

方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。 这个方法用得比较少,理解起来也很简单,看几个案例就明白了:

  let arr1 = [1, 2, 3, 4];

  // 用0来填充,从 2 ~ 4(不包含4)
  console.log(array1.fill(0, 2, 4));//[1, 2, 0, 0]

  // 用5来填充,从下标1开始,由于默认结束位置是 arr.length 所以会直接填充到最后
  console.log(array1.fill(5, 1));//[1, 5, 5, 5]

语法:arr.fill(value[, start[, end]])

6,filter()

意思很明显,就是用来筛选数组的,这个方法会返回一个新的数组,返回的值就是复合筛选条件的项。

比如,筛选长度大于5的单词

  let words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

  let result = words.filter(word => word.length > 5);

  console.log(result);
  //["exuberant", "destruction", "present"]

语法:arr.filter(callback(element[, index[, array]])[, thisArg])

filter本身接收两个参数, 第一个参数是一个函数,用来执行过滤条件, 第二个参数是执行第一个函数时指定里面的 this 指向。

在回调函数里面接收三个参数, 第一个element是当前正在处理的元素 第二个index是当前元素的索引 第三个array是当前正在处理的数组本身

案例:查找以某某字母开头的单词

  let name = ['skincare', 'dior', 'chanel', 'armand', 'lancome'];
  let filterItems = function(query){
      return name.filter((el)=>{
          return el.toLowerCase().startsWith(query);
      })
  }

  console.log(filterItems('a'));//["armand"]

7,find()

方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。 它和filter差不多

语法:arr.find(callback(element[, index[, array]])[, thisArg])

filter是遍历整个数组,把所有符合条件的放在一个数组中返回, 而find方法是找到一个之后,后面的就不再看了,直接返回找到的那个符合条件的值

注意哦,返回的是找到的那个值

案例:

  let name = ['skincare', 'dior', 'chanel', 'armand', 'lancome'];
  let filterItems = function(query){
      return name.find(el=>el.length>4);
  }

  console.log(filterItems());//"skincare";

依然是上面的案例,这里换成了find方法,筛选条件也变成了单词长度大于4,很明显有好几个单词的长度都是大于4的 但是依然只会返回第一个单词。

并且如果我们把find方法里的el打印出来,也可以发现只打印了第一项,因为第一项符合条件,所以直接返回,不再看后面的内容。

  let name = ['skincare', 'dior', 'chanel', 'armand', 'lancome'];
  let filterItems = function(query){
      return name.find(el=>{
          console.log(el);//"skincare";只循环了一遍
          return el.length>4;
      });
  }

  console.log(filterItems());//"skincare";

另外它还有个CP方法:findIndex,意思很明显,那就是返回符合条件的元素的下标。

8,findIndex()

方法返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。

语法,案例都和上面的fand方法一样,只是这里返回的是下标而已,没啥可说的,另外没有找到的话返回值也不一样,这点稍微注意一下。

9,flat()

方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回

其实就是扁平化数组,当然还可以指定深度,比如一个三维数组,指定扁平深度为1,那么数组就变成一个二维数组了。

语法:arr.flat([depth])

注意参数depth意思是深度,默认值是1

案例:

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

10,flatMap()

这个方法的话呢,很多资料都没有讲得很清楚,只是说它和map类似,但是其实它之所以叫flatMap当然是有深意的,flat是扁平化数组,而map是映射,对数组做一个统一的处理。

flatMap则是这两者的结合,在映射数组的同时,可以把结果进行扁平化

案例:

  let str = 'str arr item name';
  console.log(str.split(' ')); 
  //["str", "arr", "item", "name"]
  //字符串拆分会得到一个数组

  let arr = [str,'console log','filter items'];
  console.log(arr.map((item)=>{
      return item.split(' ');
  }));
  /*[
      ["str", "arr", "item", "name"],
      ["console", "log"],
      ["filter", "items"]
  ]*/
  //把字符串放在数组里,然后用map方法对每一个字符串进行拆分,会得到二维数组

  console.log(arr.flatMap((item)=>{
      return item.split(' ');
  }));
  //["str", "arr", "item", "name", "console", "log", "filter", "items"]
  //同样的处理方式,用flatMap得到的是一维数组

在案例中可以看到,字符串拆分会得到一个数组 如果把字符串放在数组里,然后用map方法对每一个字符串进行拆分,会得到二维数组 但是如果同样的处理方式,用flatMap得到的会是一维数组

这就是flatMap方法在处理了结果的同时,把结果进行扁平化了。但是这个扁平化的能力也是有限的,它只能扁平化一次,在深入一点就不行了,因为flatMap接收的参数和map方法保持一致,而不是和flat方法保持一致。

  let arr1 = [1, 2, 3, 4];
  console.log(arr1.flatMap(x => [[x * 2]]));
  // [[2], [4], [6], [8]]

语法:

arr.flatMap(callback(currentValue[, index[, array]]) { // return element for new_array }[, thisArg])

11,forEach()

这个方法估计大家都很熟悉了,遍历数组 以前我们用for循环语句来遍历数组,各种搞不清楚的概念,甚至还需要存下标,估计现在好多同学都不知道为什么要存下标。

现在不需要了,直接forEach,里面就有可以直接利用的下标

语法:

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

forEach配合Array.from方法一起的话就会更好用了,获取到的元素列表用Array.from转换成数组,然后直接forEach

  let list = document.querySelectorAll('li');
  Array.from(list).forEach((item,index)=>{
      item.onclick = function(){
          console.log(index);
      }
  })

有兴趣可以再返回最上方看看Array.from里的案例

12,includes()

方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。

  let array1 = [1, 2, 3];

  console.log(array1.includes(2));
  // true

语法:arr.includes(valueToFind[, fromIndex])

太简单了,直接略过

13,indexOf()

方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。 这个方法相信大家都是很熟悉了,最多的用处可能是用来判断数组里是否存在某个值了,字符串其实也有这个方法,功能类似。

  const beasts = ['ant', 'bison', 'camel', 'duck', 'bison'];
  console.log(beasts.indexOf('bison'));//1

新手的话要注意的就是下标的起始位是0,别搞混就可以了 没啥可说的

14,join()

join方法是将一个数组或者类数组用指定的字符进行拼接组成一个字符串进行返回 比如:

  let arr = [2,3.4,'lili','a','b','c'];
  console.log(arr.join('_'));
  //得到结果:2_3.4_lili_a_b_c

如果在配合字符串方法:split的话,做个数组的拷贝就很简单了,当然了,限制一维数组,如果维度比较深的话,就会有问题了:

  let arr = [2,3.4,'lili','a','b','c'];
  console.log(arr.join('_'));
  let newarr = (arr.join('_')).split('_');
  console.log(newarr);
  //得到结果:["2", "3.4", "lili", "a", "b", "c"]

语法:arr.join([separator])

参数是一个字符串,用这个字符串来链接数组的每一项,可以为空字符串,也可以不传,不传的时候默认用逗号来作为连接符

  let arr = [2,3.4,'lili','a','b','c'];
  console.log(arr.join(''));
  //得到结果:23.4liliabc
  console.log(arr.join());
  //得到结果:2,3.4,lili,a,b,c

通过调用原型方法,还可以把函数的参数链接起来:

  function fn(a, b, c) {
      var str = Array.prototype.join.apply(arguments);
      console.log(str);//lili,a,b,c
  }
  fn('lili','a','b','c');

第一期先到这里~,点赞期待后续吧!