js数组常用方法整理

js数组常用方法整理

标签:js 数组

前言:这篇文章主要是一些归纳总结,大部分参考的是MDN
的程序,也加了一些自己的理解,自己敲一遍,权当加深印象

Array实例上的方法

1.Array.from

es6中的新方法,功能和Array.prototype.slice.call()相同

用于从一个类数组或可迭代对象(string,set,map,arguments等)中创建一个新的数组实例

类数组定义:

  • 可以通过索引访问元素
  • length属性(所以当一个对象包含length属性时,也可以被看做是一个类数组)
  • 没有数组的一些方法,例如push,foreach

可迭代对象:

  • Symbol.iterater属性

语法

Array.form(arrayLike[,mapFn[,thisArg]])

function f() {
    //将参数转化为数组
    return Array.from(arguments); 
}
console.log(f(1,2,3)); //[1,2,3]

2.Array.isArray

用于判断传递的值是否是一个数组

Array.isArray([1,2,3]) //true
Array.isArray('123') //false
Array.isArray({}) //false
Array.isArray(Array.prototype) //true,没想到吧,Array.prototype也是一个数组
Array.isArray(Function.prototype) //false,但是其他原型对象就是普通对象了呢
...

判断一个数是否为数组的其他方法

  • instanceof

      var arr = [1,2,3];
      var obj = {a:1};
      var str = '123';
      arr instanceof Array //true
      obj instanceof Array //true
      str instanceof Array //true
      Array.prototype instanceof Array //false,没有办法检测出Array.prototype
    
  • Object.prototype.toString.call(arg)

    推荐!当不存在Array.isArray方法时,可以用它来做polyfill

      var arr = [1,2,3];
      var obj = {a:1};
      var str = '123';
      Object.prototype.toString.call(arr) === [object Array] //true;
      Object.prototype.toString.call(obj) === [object Array] //false;
      Object.prototype.toString.call(str) === [object Array] //false;
    

3.Array.of

用于创建一个数组

与Array构造函数的区别在于当处理单个参数时有所不同

Array.of([3]); //[3]
new Array(3); //[undefined,undefined,undefined]

Array.prototype上的方法

1.concat()

用于连接两个数组并返回合并后的新的数组,原数组不改变

var arr1 = [1,2,3];
var arr2 = [4,5,6];
arr1.concat(arr2);  //[1,2,3,4,5,6]
console.log(arr1);  //[1,2,3] ,arr1没有被改变

注意!concat方法返回的是一个浅拷贝的数组,这意味着,当原数组中有引用类型的值时,
只会把他的引用复制下来。所以当新数组或原数组中的引用类型被修改时,二者的值都会被修改

var arr1 = [1,2,3];
var arr2 = [4,[5,6]];
console.log(arr1.concat(arr2)); //[ 1, 2, 3, 4, [ 5, 6 ] ]
arr2[1].push(7);  //原数组被改变
console.log(arr1.concat(arr2)); //[ 1, 2, 3, 4, [ 5, 6, 7 ] ],新数组中的值也随之改变

2.filter(callback)

用于返回数组中符合要求的元素,并组成一个新数组

callback()函数里面接受三个参数 value,index,array

var filterValue = function(value,index,array){
    return value>10
}
var filterIndex = function(value,index,array){
    return index>0
}
var arr = [1,12, ,2,17,4]; 
arr.filter(filterValue); //[12,17]
arr.filter(filterIndex); //[12,2,17,4] ,注意数组中未被赋值或已删除的元素会被跳过

3.forEach(callback)

用于对数组中的每个元素进行处理(已删除或未被初始化的项将被跳过),无返回值

function logArrayElements(item, index, array) {
    console.log("a[" + index + "] = " + item);
}

// 注意!索引2被跳过了,因为在数组的这个位置没有项
[2, 5, ,9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[3] = 9

注意!如果数组在迭代过程中被修改了,那其他元素有可能会被跳过

var arr = [1,2,3,4];
arr.forEach(function(item,index){
    console.log('index:'+index,'item:'+item);
    if(item === 2){
        arr.shift(); 
        //把数组第一个元素移除了,导致剩下的项都上移一个位置,index为2的项现在值为4,所以3被跳过了
    }
})
// index:0 item:1
// index:1 item:2  //3被跳过了
// index:2 item:4

4.indexOf()

返回在数组中找到的第一个元素对应的索引,如果不存在,返回-1

indexOf(element[,fromIndex]) //查找元素,开始寻找的位置

var arr = [2,3,1,5,4,3,7];
arr.indexOf(3); //1 注意,只找第一个位置元素所对应的索引
arr.indexOf(6); //-1 该值不存在,返回-1
arr.indexOf(3,4); //5
arr.indexOf(3,8); //-1 后一个参数大于数组长度,不查找,直接返回-1
arr.indexOf(3,-2); //5 后一个参数为负数是表示从倒数第几个元素开始查找,这里找到的是索引值为5的3
arr.indexOf(3,-1); //-1 倒数第一个位置上只有7,找不到3,返回-1(不会再往前查找)

5.join()

用于将一个数组中的元素组合成一个新的字符串并返回,该方法不改变原数组

var arr = [1,2,3];
arr.join(); //'1,2,3' join内参数为空时,连接符默认为','
arr.join(''); //'123'

进行连接前,会先将数组中的元素转化为字符串(会隐式调用toString方法)

var arr = [1,2,null,[3,4],undefined,{a:1}];
arr.join('-'); //"1-2--3,4--[object Object]"  
//undefined,null转化为''
//[3,4].toString() => '3,4'
//obj.toString() => [object Object]

6.map()

对数组中的每一个元素执行方法,与forEach()方法类似,但是map()有返回值,
返回值为每个元素执行方法后的结果组成的新数组,此方法不改变原数组

var arr = [1,2,3];
var changedArr = arr.map(item => item*2);
//changedArr [2,4,6]
//arr [1,2,3] 原数组没有被改变

map()方法的callback接受三个参数 (item,index,array)

7.pop()/push()

pop()方法用于删除数组中的最后一个元素,该方法返回值为被删除的元素,且会改变原数组

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

数组为空时返回undefined

var arr = [];
var popNum = arr.pop();
console.log(popNum); //undefined

push()方法用于向数组末尾推进一个新的元素,并返回新数组的长度

var arr = [1,2];
var renturnNum = arr.push(4);
//arr [1,2,4]
//returnNum 3

8.reduce()

这个方法...唔,官方解释是

reduce() 方法对累加器和数组中的每个元素(从左到右)应用一个函数,将其减少为单个值。

光看说明不太好理解,下面举几个例子

[0, 1, 2, 3].reduce(function (a, b) {
  console.log('accumulator:'+a,'currentValue:'+b,'return:'+(a+b));
  return a + b;
}, 0);
//accumulator:0 currentValue:0 return:0
//accumulator:0 currentValue:1 return:1
//accumulator:1 currentValue:2 return:3
//accumulator:3 currentValue:3 return:6

可以看到,第一个参数,也就是accumulator的值都是上一次的返回值
,所以这个函数的实现其实就类似于x+=x这种累加一样

我们来具体看看这个函数的一些参数

reduce(callback[,initialValue])接受两个参数

  • callback(accumulator,currentValue,currentIndex,array)

  • initialValue 为 accumulate的初始值

    • 不提供初始值时,accumulator取数组的第一个值,cuurentValue为数组的第二个值
    • 提供初始值时,acuumulator取初始值,currentValue取数组的第一个值

接下来我们来看一下利用reduce实现的几个功能

  • 将二维数组转化为一维

      var arr = [[1,2],[3,4],[5,6]];
      arr.reduce(function(a,b){
          return a.concat(b);
      },[]);
      //[1,2,3,4,5,6]
    
  • 计算数组中每个元素出现的次数

      var arr = ['a','b','a'];
      arr.reduce(function(a,b){
          if (b in a){
              a[b]++;
          }
          else{
              a[b] = 1;
          }
          return a
      },{});
      //{a:2,b:1}
    
  • 数组去重

      var arr = [1,1,2,3,4,4,1];
      arr.reduce(function(a,b){
          if(a.indexOf(b) === -1){
              a.push(b)
          }
          return a 
      },[]);
    

forEach(),map()方法对比一下,我们可以总结一下

相同点

  • 都遍历了整个数组

不同点

  • forEach 无返回值

  • map 返回的是遍历每个元素执行回调后的返回值形成的数组,我们用上面的计算数组中每个元素出现次数的题目来做一下对比

      var arr = ['a','b','a'];
      arr.map(function(item){
          var result = {};
          if (item in result){
              result[item]++;
          }
          else{
              result[item] = 1;
          }
          return result
      });
      //[{a:2},{b:1}]
    
  • reduce 返回的是遍历完成后的一个‘总值’

9.reverse()

用于将数组中的元素颠倒,该方法改变原数组

var arr = [1,2,3];
arr.reverse(); //[3,2,1]
//arr [3,2,1]

10.shift()/unshift()

shift()用于删除数组的第一个元素,返回被删除的元素

unshift()用于向数组开头添加元素,返回新数组的长度

二者都会改变原数组

用法与pop/push类似

var arr = [1,2,3];
arr.shift(1); //arr [2,3]
arr.unshift(4,5); //arr [4,5,2,3]

11.slice()/splice()

slice 返回一个从开始到结束的一个浅拷贝的数组,该方法不会改变原数组

var arr = [1,2,3,4];
arr.slice(0,2); //[1,2]

注意,返回的数组是浅拷贝

var obj = {a:2}
var arr = [1,2,obj];
var result = arr.slice(); //[1,2,{a:2}]
obj.a = 3;
//result [1,2,{a:3}]

可以用slice方法将类数组转化为数组

var str = 'wrma';
[].slice.call(str);
//['w','r','m','a']

splice 通过删除/添加元素来更改一个数组的内容,返回值为被删除的元素组成的数组

语法 array.splice(start, deleteCount, item1, item2, ...)

var arr = [1,2,3,4];
var result = arr.splice(1,2,'a','b','c'); //[1,'a','b','c',4]
//arr [2,3] 原数组被改变

12.sort()

sort方法对数组进行排序,返回排序后的数组

可传入回调函数使数组按照指定的规律来进行排序,若省略则按照元素转化为字符串的各个字符的Unicode位点进行排序

var arr1 = ['ab','az','A',1,2];
arr1.sort(); //[1, 2, "A", "ab", "az"] 按照unicode位点排序
//数字在字母前,大写字母在小写字母前

var arr2 = [1,10,21,2];
arr2.sort(); //[1,10,2,21] 10的Unicode位点在2之前
arr2.sort(function(a,b){
    return a-b
})
//[1,2,10,21]

13.toString()

数组的toString方法覆盖了Object的toString方法,将数组转化为字符串,相当于join()方法

var arr = [1,2,{a:3},[4,5]]
arr.toString(); //'1,2,3'

归纳

最后我们来进行一些归纳

  • 改变原数组的方法

    pop()/push()/shift()/unshift()/reverse()/splice()/sort()

  • splice()/shift()/pop() 这些删除元素的操作,返回的都是被删除的元素或是被删除元素组成的数组

  • push()/unshift() 这些添加元素的操作,返回值均为新数组的长度

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