JS数组方法全面的总结

本文总结了数组所有的方法。

1. 检测对象是不是数组

instanceof操作符

Array.isArray()方法

   var color = new Array("red", "green");
   console.log(Array.isArray(color));   //true

2. 转换方法

toString()

该方法会输出每一项,并以','连接,实际上该方法会调用数组中每一项的toString()方法,然后拼接得到的每一项的字符串。

 var color = new Array("red", "green");
 console.log(color.toString());   // red,green
 alert(color);            // red,green
 console.log(color);          // ["red","green"]

toLocaleString()

该方法会输出每一项,并以','连接,实际上该方法会调用数组中每一项的toLocaleString()方法,然后拼接得到的每一项的字符串。一般都会返回与toString()相同的值

 var color = new Array("red", "green");
 console.log(color.toLocaleString());   // red,green

valueOf()

该方法输出整个数组的字符串形式

var color = new Array("red", "green");
 console.log(color.valueOf());   // ["red","green"]

join()

该方法接收一个字符串,然后以该字符串为间隔,将数组中的每一项拼接起来

var color = new Array("red", "green");
 console.log(color.join('&&'));   // red&&green

3. 栈方法和队列方法

栈方法push()和pop()

栈是一种LIFO("LAST-In-First-Out"后进先出)的数据结构。
有两个方法,push()和pop().

  • push()接受一个或者多个参数,将它们添加到数组末尾处,返回添加后数组的长度
  • pop()则从数组中移除最后一项,并返回该项的值。

队列方法unshift()和shift()

队列是一种FIFO("First-In-First-Out"先进先出)的数据结构。
有两个方法,unshift()和shift().

  • unshift()与push()类似,只不过是在数组的最前面添加一项或多项

    var color = new Array("red", "green");
    color.unshift("blue","yellow");
    console.log(color);            // ["blue", "yellow", "red", "green"]
    
  • shift()与pop()类似,是返回数组的最前面一项

4. 排序方法

有两种排序方法,reverse()和sort()。

reverse()

reverse()方法会反转数组项的顺序。

sort()

sort()默认按照升序重新排列数组,而顺序的决定是由每一项转换为字符串后进行比较的。

var values = [0, 1, 5, 10, 15];
values.sort();
console.log(values)   //   [0, 1, 10, 15, 5], 因为转换为字符串后,10在5前面

sort()还可以接受一个函数作为参数,根据函数的返回值进行排序。这个函数接受两个值作为参数,排序原则如下:
参数1在参数2前面,返回负数,参数1在参数2后面,返回正数,两个参数相等,则返回0.

// 先创建一个简单的比较函数,该函数接受两个值做参数,本函数按照升序排列
function compare(value1, value2){
  if(value1 < value2){
      return -1;
  }else if(value1 > value2){
      return 1;
  }else {
      return 0;
  }
}
// 然后将该函数传入sort()方法中进行比较
var values = [0, 5, 1, 15, 10];
values.sort(compare);
console.log(values);          // [0, 1, 5, 10, 15]

sort()内部是根据冒泡法排序的,不断比较两个数的大小。

5. 操作方法

拼接数组concat()

该方法可以接收一个或多个参数,并新建一个当前数组的副本,将参数拼接到该副本末尾,然后返回该副本数组。
参数主要有两种类型:

  1. 参数是数组,则将数组中的每一项添加到副本数组的末尾
  2. 参数不是数组,则直接将其添加到副本数组的末尾

裁减数组slice()

该方法基于当前数组创建一个新的数组,接收一个或者两个参数,用于指定返回项的起始和结束位置。

  1. 当值传入一个参数时,返回从参数指定位置开始到数组末尾的所有项
  2. 当传入两个参数时,返回起始和结束位置之间的的但不包括结束位置的项。
  3. 两个参数均可以接收负数,会以数组的长度值加上该负数,然后计算需要返回的项。

修改数组splice()

该方法可以增加,减少或修改数组中的一项或多项。该方法接收一个或多个参数,先从指定位置删除项,然后添加任意数量的项。
该方法始终会返回一个数组,数组中包含被删除的返回项。

  • 参数1指定需要删除的项的起始位置
  • 参数2指定需要删除的项的数量
  • 参数3-参数n指定需要向数组中添加的项

所以根据传入参数的数量,有以下情况:

  1. 不传入参数,则不对数组做任何改变

    var array = [1,2,3,4];
    console.log(array.splice());   // []
    console.log(array);           // [1,2,3,4]
    
  2. 传入一个数值参数,则从数组中删除指定位置和数组末尾之间的所有项

     var array = [1,2,3,4];
     console.log(array.splice(2));   // [3,4]
     console.log(array);      // [1,2]
    
  3. 传入两个数值参数,则删除数组中从指定位置开始的指定数量的项
    var array = [1,2,3,4]; console.log(array.splice(2,1)); // [3] console.log(array); // [1,2,4]

  4. 传入三个或三个以上的参数,则先删除指定位置开始的指定数量的项,然后在该位置添加其他参数所指示的项

      ```
       var array = [1,2,3,4,5,6];
       console.log(array.splice(2,1,"red","green"));    // [3]
       console.log(array);           // [1, 2, "red", "green", 4, 5, 6]
      ```
    

copyWithin()

copyWithin()方法在数组内部将一部分复制到另一部分,而不改变数组的大小,然后返回修改后的数组。该方法接收一个至三个参数。参数含义如下:

  • 第一个参数是一个索引值,被复制的序列将放到以该索引为起始的位置上。为必需参数。
  • 第二个参数代表将要被复制的部分的起始位置。非必需参数,默认为0。
  • 第三个参数代表将要被复制的部分的结束位置,不包括结束位置。非必需参数,默认为array.length-1

以上三个参数都接收负值,会自动加上数组的长度值,转换为正值。看一些例子吧。
[11, 22, 33, 44, 55].copyWithin(-2); // [11, 22, 33, 11, 22]
上面代码复制到的索引位置是 5-2=3,由于后两个参数没有,所以复制的值是[11,22,33,44,55],但是由于该方法不改变数组的大小,所以仅仅是将11和22复制到44和55的位置。
[11, 22, 33, 44, 55].copyWithin(0, 3); // [44, 55, 33, 44, 55]
上面的代码复制到的索引位置是 0,复制区域开始的索引位置是3,第三个参数没有,所以会一直复制直到末尾,复制的值是[44,55], 覆盖了11和22
[11, 22, 33, 44, 55].copyWithin(1, 3, 4);// [11, 44, 33, 44, 55]
上面的代码复制到的索引位置是1,复制区域开始的索引位置是3,第三个参数是4,所以只会复制位置3的值44,覆盖了22

fill()

该方法在指定位置处填充一个固定的值。方法接收三个参数:

  • param1,指定填充的值。必需参数。
  • param2, 指定填充开始的位置。非必需参数,默认为0
  • param3, 指定填充结束的位置,但不包括结束的位置。默认为数组的长度值。
[1, 2, 3].fill(4);               // [4, 4, 4]
[1, 2, 3].fill(4, 1);            // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);         // [1, 4, 3]

6. 位置方法

数组有两个位置方法indexOf()lastIndexOf()。两个方法都接收一个或两个参数,第一个参数指定要查找的项,第二个参数是可选的,表示查找开始的位置。两个方法的区别是indexOf()从前往后开始查找,返回指定项第一次出现的位置,lastIndexOf()从后往前开始查找,返回指定项第一次出现的位置。若没有查找到指定项,则两个方法均返回-1。

  1. 传入一个参数
var array = ['H', 'E', 'L', 'L', 'O'];
console.log(array.indexOf('L'));       //      2
console.log(array.lastIndexOf('L'));       //  3
  1. 传入两个参数
var array = ['H', 'E', 'L', 'L', 'O'];
console.log(array.indexOf('L', 3));   // 3 ,忽略了array[2]
console.log(array.lastIndexOf('L', 2));   // 2 忽略了array[3]

有两个需要注意的事项,

  1. 数组中的项和传入参数作比较时,用的是===全等号,即必须严格相等
  2. lastIndexOf()返回的索引值是基于正序的索引值,而非基于倒序的索引值
var array = ['H', 'E', 'L', 'L', 'O'];
console.log(array.lastIndexOf('O'));     // 返回4,而非0

7. 归并方法

有两个归并数组的方法reduce()reduceRight()。这两个方法都会迭代数组中的所有项,然后构建一个返回值,其中reduce()从数组的第一项开始,遍历到最后,reduceRight()从最后一项开始,遍历到第一项。
这两个方法都接收两个参数: 第一个参数是在每一项上调用的函数,第二个参数是可选的,作为归并基础的初始值。
作为第一个参数的函数接收4个参数: 前一个值,当前值,当前项的索引和该数组对象。这个函数返回的值,将作为下一次迭代操作中函数的第一个参数。函数的第二个参数是数组的下一项。
第一次迭代发生在数组的第二项上,函数的第一个值是数组的第一项,第二个参数是数组的第二项。

  • 传入一个参数
function add(prev, curv, index, array){
   return prev + curv;
}
var values = [1, 2, 3, 4, 5];
var sum = values.reduce(add);
console.log(sum);         //15
上面的代码中,第一次迭代中,传入``add()``中的参数如下:prev = 1, curv = 2,index = 1,array = values,第一次迭代后,``add()``函数返回值是1+2=3。
第二次迭代中,传入``add()``中的参数如下:prev = 3,curv = 3,index = 1,array = values,第二次迭代后,``add()``函数返回值是3+3=6。依次向后迭代...
``reduceRight()``则是从最后一项开始往前迭代。
  • 传入两个参数
    传入两个参数时,第二个参数将作为归并基础的初始值。也就是说,传入该参数后,用该参数加上后面最终迭代得到的值。

function add(prev, curv, index, array){
return prev + curv;
}
var values = [1, 2, 3, 4, 5];
var sum = values.reduce(add, 10);
console.log(sum); // 25, 在迭代得到的值上面加上了10


## 8. 创建数组的新方法
### [Array.from()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from?v=control)
该方法基于一个类数组的对象或可迭代的对象,创建一个新的数组实例。该方法接收一至三个参数,各个参数如下:
1. 参数1是一个类数组对象或可迭代对象,方法基于该对象创建数组。函数的返回值将作为新数组中的每一项的值。必需的参数。
2. 参数2是一个函数,数组的每一项都会调用该函数。非必需参数。
3. 参数3指定在参数2中,this所代表的对象。非必需参数。

类数组对象是具有length属性并含有被编上索引的元素的对象,如NodeList对象。
可迭代对象是可以获得其中的元素的对象,如[Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)和[Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)

var str = "hello";
Array.from(str, x => x + x); // ["hh", "ee", "ll", "ll", "oo"]

上面的代码中接收一个字符串为第一个参数,接收箭头函数作为第二个参数。在箭头函数中,对每一项做了复制操作,然后返回得到的值,作为数组的每一项。

### [Array.of()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of?v=control)
该方法接收一系列参数,并以这些参数为项,创建一个数组,并返回该数组。

var arra = Array.of("red", "green", "blue");
console.log(arra); // ["red", "green", "blue"]

该方法与构造函数``Array()``类似,但有一点不同。当接收到只有**一个**数值类型的参数时,``Array()``会创建一个数值参数指定的长度的数组,而``Array.of()``会将该数值作为数组中的项添加进数组。

var arra1 = new Array(7);
console.log(arra1); // [undefined × 7]
var arra2 = Array.of(7);
console.log(arra2); // [7]


## 9. 迭代方法
### every()
该方法接收一个函数作为参数,对数组中的每一项运行该函数,若对每一项,指定函数都返回true,则最终``every()``方法返回true。该方法还接收一个可选的第二个参数,指定在运行函数时,函数中this所代表的对象。
  ```
  var num = [1,2,3];
  console.log(num.every( value => {
      if(value > 0){return true;}
      return false;
  }));  // true,因为每一项都大于0
  console.log(num.every( value => {
      if(value > 1){return true;}
      return false;
  })); //false,因为1-1=0,转换为布尔值是false
  ```
### some()
该方法与``every()``对应,``every()``是所有项均返回true,最终才返回true,``some()``是只要有至少一个返回true,该方法就会返回true.
  ```
  var num = [1,2,3];
  console.log(num.some( value => {
      if(value > 1){return true;}
      return false;
  }));  // true,因为至少有一项大于1
  console.log(num.some( value => {
      if(value > 3){return true;}
      return false;
  })); //false,都不大于3
  ```

### filter()
该方法接收一个函数作为参数,对数组中的每一项运行该函数,若对某一项,指定函数返回true,则将该项添加到一个新建的数组中,最后返回该数组。该方法还接收一个可选的第二个参数,指定在运行函数时,函数中this所代表的对象。
   ```
  var num = [1,2,3];
  console.log(num.filter( value => {
      if(value > 0){return true;}
      return false;
  }));  // [1,2,3]
  console.log(num.filter( value => {
      if(value > 1){return true;}
      return false;
  })); // [2, 3]
  ```

### forEach()
该方法接收一个函数作为参数,对数组中的每一项运行该函数,该方法没有返回值。作用于for循环类似。
该方法还接收一个可选的第二个参数,指定在运行函数时,函数中this所代表的对象。

### map()
该方法接收一个函数作为参数,对数组中的每一项运行该函数,返回由该函数的返回值组成的数组。该方法还接收一个可选的第二个参数,指定在运行函数时,函数中this所代表的对象。
  ```
  var num = [1,2,3];
  console.log(num.map( value => { return value * value; }));  // [1, 4, 9]
  ```
### find()
该方法接受一个函数作为参数,对数组中的每一项运行该函数,直到某一次运行后返回true,此时,该方法将返回该项的值。若所有项的运行结果都是fase,最终将返回undefined。所以该方法并不一定遍历数组中所有项。该方法还接收一个可选的第二个参数,指定在运行函数时,函数中this所代表的对象。
  ```
   var num = [1,2,3];
  console.log(num.find( value => {
      if(value === 2){return true;}
      return false;
  }));  // 2
  ```
看如下代码
  ```
  var inventory = [
      {name: 'apples', quantity: 2},
      {name: 'bananas', quantity: 0},
      {name: 'cherries', quantity: 5}
  ];

  function findCherries(fruit) {
      return fruit.name === 'cherries';
  }

  console.log(inventory.find(findCherries));
  // { name: 'cherries', quantity: 5 }
  ```

### findIndex()
该方法与``find()``类似,只不过当找到符合条件的项时,会返回该项的索引值。

var num = [1,2,3];
console.log(num.findIndex( value => {
if(value === 2){return true;}
return false;
})); // 1


**注意**:以上方法中,接收的作为参数的函数,都可以接受三个参数,分别是数组每一项的**当前值**,**当前索引值**,以及调用方法的**数组本身**.

var num = [1,2,3];
num.forEach( (value, index, array) => {
console.log("数组为->"+array + ":");
console.log(index + "->" + value);
});
// 数组为->1,2,3: 0->1
// 数组为->1,2,3: 1->2
// 数组为->1,2,3: 2->3


## 10. 其他方法
### entries()
``entries()``方法返回一个新建的数组迭代对象,对象中包含了每一项的key/value组成的数组。看代码

var a = ['a', 'b', 'c'];
var iterator = a.entries();
for(let e of iterator){
console.log(e);
}
// [0, 'a']
// [1, 'b']
// [2, 'c']


### keys()
该方法返回一个可迭代对象,其中包含了数组中每一项的索引值

var arr = ['a', 'b', 'c'];
var iterator = arr.keys();

console.log(iterator.next()); // { value: 0, done: false }
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: undefined, done: true }


### values()
该方法于``keys()``方法对应,也是返回一个可迭代对象,其中包含数组中每一项的值
var a = ['w', 'y', 'k', 'o', 'p'];
var iterator = a.values();

console.log(iterator.next().value); // w
console.log(iterator.next().value); // y
console.log(iterator.next().value); // k
console.log(iterator.next().value); // o
console.log(iterator.next().value); // p

### includes()
该方法用于查找数组中是否包含等于指定值的项。接收两个参数:
- param1,指定被查找是否存在于数组中的值,必须。
- param2,指定查找开始的索引值,默认为0,非必需。当传入负值时,将加上数组的长度值。

[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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,191评论 0 4
  • 由于最近都在freecodecamp上刷代码,运用了很多JavaScript数组的方法,因此做了一份关于JavaS...
    2bc5f46e925b阅读 1,951评论 0 16
  • Javascript有很多数组的方法,有的人有W3C的API,还可以去MDN上去找,但是我觉得API上说的不全,M...
    顽皮的雪狐七七阅读 4,040评论 0 6
  • 本章内容 使用对象 创建并操作数组 理解基本的 JavaScript 类型 使用基本类型和基本包装类型 引用类型的...
    闷油瓶小张阅读 670评论 0 0
  • 时间不知不觉的就过去了百年,在这一百年里他们对彼此十分了解。原十分开朗有主见,对什么都好奇。初不爱说话,但是很听原...
    花格语气阅读 312评论 0 0