javascript中数组的方法你真的都了解吗?

释放双眼,带上耳机,听听看~!

本篇文章主要讲述ES5中的数组,包括数组两种创建方式,属性,以及 9 大类 ,总共23个操作方法,非常全面,看完之后ES5数组这一部分基本都了解了,下一篇文章,我会讲述ES6中对数组的加成,新增了哪些方法,以及定型数组,类数组和类数组的所有方法,记得关注哦!

数组作为javascript中最常用的数据类型之一,掌握好数组的方法在日常的开发中是非常有必要的,javascript中的数组相比其他语言来说更灵活,因为数组的每一项都可以是不同的数据类型,可以是对象,数组,字符串,数值等等,接下来一点一点的了解吧!

1.数组的创建

说到数组首先肯定是创建,只有创建或者声明一个变量是数组之后才可以使用它,以及他的一些属性和方法。数组的创建有两种方式,即,构造函数式和数组字面量式。

  • 第一种构造函数式创建,利用new Array来创建,下面先上一段例子:

    var arr =  new Array();
    var arr1 = new Array(3);
    var arr2 = new Array(\"xiao mage\");
    var arr3 = new Array(12,34,);
    var arr4 = new Array(,,,,,);
    console.log(arr);               //[]            
    console.log(arr1);          //[empty*3]
    console.log(arr2);          //[\"xiao mage\"]
    console.log(arr3);          //在谷歌浏览器中报错,不能多逗号,注意
    console.log(arr4);          //在谷歌浏览器中报错,这样也是不行的

    分析一下,第一行创建了一个空数组;第二行创建了一个长度为3的空数组,注意这个3是数组的长度为3,不是数组的第一项是数值3,切记!在下一篇讲到的类数组方法Array.of()方法就可以创建数值3;第三个是创建了一个字符串数组,里面只有一个值;第四行,第五行都目前chrome浏览器无法编译通过,写法有问题,特意列出来注意一下。 在使用Array 的时候new也可以省略,其效果也是一样的。

  • 第二种是数组字面量创建数组,即直接用[]。

    var arr = [];                   //[]
    var arr1 =[12,34,];             //[12,34]
    var arr2 = [,,,,] ;             //[empty*4]
    var arr3 = [\"xiaomage\"];        //[\"xiaomage\"]
    var arr4 = [1,2,3,4,5];         //[1,2,3,4,5]
    var arr5 = [1,{\"a\":1,\"b\":2},[434,798],\"xiaomage\"];
    console.log(arr);               //[]            
    console.log(arr1);          //[12,34]
    console.log(arr2);          //[empty*4]
    console.log(arr3);          //[\"xiaomage\"]
    console.log(arr4);          //[1,2,3,4,5]
    console.log(arr5);          //[1, {…}, Array(2), \"xiaomage\"],展开就是[1,{\"a\":1,\"b\":2},[434,798],\"xiaomage\"]
    

    再分析一下,第一行也是创建了一个空数组;第二行创建了一个长度为2的数组,数组中包含12,34,在有的浏览器中长度为3,注意一下。第三行创建了一个长度为4的空数组,数组的每一项值是undefined,有的浏览器也可能数组的长度是5。第四行创建了一项含有字符串的数组;第五行创建一个全是数值的数组,最后一行创建了一个长度为4的数组,每一项都是不同的数据类型。

    注意: 1. var arr = new Array(,,,,);是报错的,而var arr = [,,,,];是可以创建数组的;以及var arr = new Array(12,34,)也是报错的,而var arr = [12,34,]是可以的,这些注意不要搞混淆了,日常工作中都不推荐此种方法创建数组; 2. 虽然两种方法都可以创建数组,但是数组字面量要比构造函数的性能好,原因是:json格式的语法浏览器引擎能直接解析,而new Array需要调用Array的构造器。日常工作中可以使用前者,方便快速省性能。

2. length属性

大家都知道length属性表示数组的长度为多少,现在用构造函数式和数组字面量式创建一个长度为10的空数组,试试看:

var  arr = new  Array(10);
console.log(arr.length) ;               //10
var arr1 = [];
console.log(arr1.length);               //0
arr.length = 10;
console.log(arr);                       //[empty*10]
var arr2 = [,,,,,,,,,,];
console.log(arr2.length);               //10

现在用数组的length属性来操作数组的长度,不用arr.pop()和arr.shift()方法怎么来搞呢?

var arr1 = [0,1,2,3,4,5,6,7,8,9];
console.log(arr1.length);          //10
arr1.length = 8;
console.log(arr1);                //[0,1,2,3,4,5,6,7]

var arr2 = [1,2];
arr2.length = 100;
console.log(arr2) ;                 //[1, 2, empty × 98]
console.log(arr2[10]);               //undefined
arr2[99]  = \'xiaomage\';
console.log(arr2)                   //[1, 2, empty × 97, \"xiaomage\"]
console.log(arr2.length);
arr2[arr2.length] = 1100000;
console.log(arr2);                  //[1, 2, empty × 97, \"xiaomage\",1100000]

分析一下:首先arr1 是一个长度为10的数组,当把数组的长度成为8的时候,此时会从数组的第一个元素开始向后截取8个作为数组的新值,此操作会改变数组。 arr2是一个长度为2的数组,将数组的长度设为100后,将依次为数组的剩余97项设置值为undefined,当再改变某一项的元素的时候就是正常的赋值了,最后一个给数组添加一项,当前数组的最后一项的索引是length-1,当arr.length就是添加一项。

3.数组的检测

数组作为引用类型之一,检测方法有两种:instanceof和isArray。其中instanceof适用于在一个网页或者一个全局作用域的情况比较实用,随着前端框架越来越多,在项目 中引入太多的框架的时候,每个框架对数组可能进行过二次封装,这样导致一个问题就是instanceof 返回的结果可能会不同,使用时得注意,基本用法如下:

var arr = [] ;
console.log(arr instanceof Array);          //true

基于以上的问题,ES5又新增了新的检测方法,isArray 来确定某个值到底是不是数组,而不用管其他的作用域问题。写法如下:

var arr = [];
console.log(Array.isArray(arr));        //true

4.类栈操作相关

数据结构栈的特点就是后进先出(LIFO, last-in-first-out) ,比喻成容器罐好理解点,最后放的在上面,拿的时候也先从上面拿,操作推入和弹出,都发生在栈的顶部,javascript数组中有专门的方法push()和pop()来模拟栈的操作。

push()方法,接受不限制个数的参数,在数组的末尾插入元素,返回值是修改后的数组的长度,此方法会改变原数组;pop()方法,不接受参数,从数组的末尾来删除最后一个元素,返回值是删除的元素,此方法也会改变原数组。下面我们来看看具体用法:

var arr = [92,09,13,\'xiaomage\'];
console.log(arr.length);                    //4
var count = arr.push(\'daqianduan\',89);
console.log(count);                         //6
console.log(arr);                           //[92, 9, 13, \"xiaomage\", \"daqianduan\", 89]
var item = arr.pop();
console.log(item);                          //89
console.log(arr);                           //[92, 9, 13, \"xiaomage\", \"daqianduan\"]

5.类队列操作相关

上面聊完了栈,现在来看看队列,相信这两个词大家都不陌生,队列的特点是:先进先出(FIFO , first-in-first-out),看做是一个空的管道比较好理解,从一端进入,另一端出去。javscript数组提供了shift()和push()方法来模拟队列的特点。

shift() , 从数组的头部删除一个元素,返回值是删除的元素,此方法会改变原数组,看看使用情况:

var arr = [25,78,{\'a\':1,\'b\':10},\'javascript\'];
var count = arr.push([12,34]);
console.log(count);                 //5
console.log(arr);                   //[25, 78, {…}, \"javascript\", Array(2)]
var item = arr.shift();
console.log(item);                  //25
console.log(arr);                   //[78, {…}, \"javascript\",Array(2)]
console.log(arr.length);            //4

跟shift()方法结果刚好相反的是unshift()方法,shift()是从数组头部删除元素,而unshift()刚好是从头部添加元素,接受不限个数的参数,返回值是改变后的数组的长度,此方法会改变数组,其实,这个方法效果跟push()一样,只不过一个在数组前面插入,一个在后面插入,看看效果:

var arr = [\'xiaomage\',[15],90,23];
arr.push(\'string1\',10);
console.log(arr);                               //[\"xiaomage\", Array(1), 90, 23, \"string1\", 10]
var count = arr.unshift([34,45],\'string2\');
console.log(count);                             //8
console.log(arr);                               //[Array(2), \"string2\", \"xiaomage\", Array(1), 90, 23, \"string1\", 10]
arr.shift();
console.log(arr);                               //[Array(2), \"string2\", \"xiaomage\", Array(1), 90, 23, \"string1\", 10]
arr.pop();
console.log(arr);                               //[\"string2\", \"xiaomage\", Array(1), 90, 23, \"string1\"]

6.数组的重排序方法

说到数组的重排序方我们肯定想到的是reverse()和sort()方法,来了解一下这两个方法,首先:

reverse()方法是将数组进行反转,调换顺序,比较简单哈,返回结果是改变顺序后的数组,此方法会改变原数组。

var arr = [0 ,1 ,2 ,4,5,10,15];
var arr2 = arr.reverse();
console.log(arr2);                  //[15, 10, 5, 4, 2, 1, 0]
console.log(arr);                   //[15, 10, 5, 4, 2, 1, 0]

即返回的结果就是原数组改变后的结果,二者是相等的,但是这个方法只能反转不方便啊,比如说我想把数组按照升序或者降序排列,reverse就干不了,这时候就得用到sort()方法了。

sort()方法,默认是按照升序排列的,返回的结果也是改变后的数组,此方法会改变原数组。

var arr = [0,1,10000000,15,10,5];
var arr1 = arr.sort();
console.log(arr);                   //[0, 1, 10, 10000000, 15, 5]
console.log(arr1);                  //[0, 1, 10, 10000000, 15, 5]

首先,同学们可能会疑问,怎么返回的结果跟我预想的不一样呢,不应该是[0 , 1 , 5, 10 ,15 , 10000000]吗?这是因为当调用sort()方法的时候,首先sort()会把数组的每一项值都先调用toString()方法变成对应的字符串,即[\'0\',\'1\',\'10000000\',\'15\',\'10\',\'5\'];第二步再进行字符串的比较,挨个字符比较。上一篇《一篇文章搞定javascript中的字符串》我讲过字符串的比较方法,不了解的回过去看一下哈,然后得出结果[0, 1, 10, 10000000, 15, 5]。

这里同学可能就有疑问,我就想要结果[0 , 1 , 5, 10 ,15 , 10000000]。也不是不可以,这时候我们可以使用sort()方法的参数来进行处理,此方法接受一个比较函数来作为一个参数,里面我们可以自定义我们想要的结果,是想让升序呢,还是降序都可以实现。

var arr = [0,1,10000000,15,10,5];
var arr1 = arr.sort(compareArray);
console.log(arr1);                      //[0, 1, 5, 10, 15, 10000000]
console.log(arr);                       //[0, 1, 5, 10, 15, 10000000]

function compareArray(item1,item2){
    if(item1 < item2 ){
        return -1 ;
    }else if(item1 > item2 ){
        return 1 ;
    }else{
        return  0 ;
    }
}

是的,我们想要的结果得到了,这里解释一下compareArray,次方法作为sort()方法的参数,接受两个参数,分别是要比较的数组的两项,返回结果是三种,大于0 ,小于0,或者等于0.然后sort根据返回的结果,如果小于零则不用换位置,如果大于零则需要调换位置,等于零则代表相等,不做处理,进行下一次的比较。

前面我们看了升序的写法,那么降序也是一样的,只不过把返回值调换一下就可以了。

var arr = [0,1,10000000,15,10,5];
var arr1 = arr.sort(compareArray);
console.log(arr1);                      //[10000000, 15, 10, 5, 1, 0]
console.log(arr);                       //[10000000, 15, 10, 5, 1, 0]
function compareArray(item1,item2){
    if(item1 < item2 ){
        return 1 ;
    }else if(item1 > item2 ){
        return -1 ;
    }else{
        return  0 ;
    }
}

//这里我只是把sort的参数方法提出来了,下面这样写也是等价的。
var arr2 = arr.sort(function(item1 , item2){
     if(item1 < item2 ){
        return 1 ;
    }else if(item1 > item2 ){
        return -1 ;
    }else{
        return  0 ;
    }
});
console.log(arr2);

看着一个数组的比较,写了这么多的代码,有没有高级写法,简写的让自己的代码看起来更有逼格一点呢,当然有啊,这里我们用到ES6来改写一下:

var arr = [0,1,10000000,15,10,5];
arr.sort((item1 , item2)=> item1 - item2);
console.log(arr);               //[0, 1, 5, 10, 15, 10000000]  

简单明了,这是升序的结果,如果想要降序用item2 - item1就可以。这里稍微解释一下,第一,箭头函数是原始函数的简写,方便轻巧,第二,当箭头函数中代码块中只有一行语句并且包含return时,可以省略{}和return。关于ES6后面的文章中我会在后面的文章中写,记得关注。

7.数组的转换方法

数组的转换方法有三个toString(),toLocaleString(),valueOf().

toString(),将数组转换成字符串 ,返回值是改变后的字符串,此方法不会改变数组。

var arr = [1, \'xiaoma\' , [1,2,3], 10000];
var str = arr.toString();
console.log(arr);           //(4) [1, \"xiaoma\", Array(3), 1000]
console.log(str);           //1,xiaoma,1,2,3,1000

toLocaleString(),在有的时候,结果和toString()一样,当然也不总是 一样,,这得跟当地的编码有关,使用时也得注意,此方法转换时每一项都调用toLocaleString()。

var arr = [1, \'xiaoma\' , [1,2,3], 1000000];
var str = arr.toLocaleString();
console.log(arr);           //[1, \"xiaoma\", Array(3), 1000000]
console.log(str);           //1,xiaoma,1,2,3,1,000,000
var arr2 = str.split(\',\');
console.log(arr2);          //(8) [\"1\", \"xiaoma\", \"1\", \"2\", \"3\", \"1\", \"000\", \"000\"]

在我们地区,超过三位以上的数字会以 ’,‘ 隔开的。所以得到的结果会和toString()不同。

valueOf(),该方法是数组对象的默认内置方法,返回Array对象的原始值,该原始值由Array对象派生的所有对象继承,此方法不会改变原数组。

var arr = [1, \'xiaoma\' , [1,2,3], 1000000];
var arr2 = arr.valeuOf();
console.log(arr);           //[1, \"xiaoma\", Array(3), 1000000]
console.log(arr2);          // [1, \"xiaoma\", Array(3), 1000000]

注意:所有的对象含有toString(),toLocaleString(),valueOf()这三个内置方法,并不是数组独有。

8.数组的操作方法

  • concat():顾名思义,连接,将一些数组拼接到一起形成一个新的数组,此方法不改变原数组。可以接受任意多个参数,参数可以是数组,字符串,数值都可以。当不传参数的时候只返回原数组的副本。
var arr = [\'xiaoma\' , 324, 90, 33] ;
var arr1 = arr.concat();
var arr2 = arr.concat(\'javascript\',[1,3,,4],[5,6,7],10);
console.log(arr);           //[\"xiaoma\", 324, 90, 33]
console.log(arr1);          //[\"xiaoma\", 324, 90, 33]
console.log(arr2);          //[\"xiaoma\", 324, 90, 33, \"javascript\", 1, 3, empty, 4, 5, 6, 7, 10]
  • slice():即截取,接受一个或者两个参数,第一个参数是要截取的起始项,第二个参数是截止项。当只有一个参数的时候,默认是从起始项到数组末尾,该方法返回的是一个新数组,不改变原数组。
var arr = [\'xiaoma\', [1,2,3],10,45,{\'a\':1,\'b\':2},\'javascript\'];
var newArr = arr.slice(1);
var newArr2 = arr.slice(2,4);
console.log(arr);               //[\"xiaoma\", Array(3), 10, 45, {…}, \"javascript\"]
console.log(newArr);            //[Array(3), 10, 45, {…}, \"javascript\"]
console.log(newArr2);           // [10, 45]

当slice的参数中含有负数的参数的时候,则用数组的长度+负参数作为新的参数值再开始截取,计算后的第二个参数比第一个参数小时,则返回的是一个空数组。

var arr = [\'xiaoma\', [1,2,3],10,45,{\'a\':1,\'b\':2},\'javascript\'];
var newArr = arr.slice(-3,-2);  //重新计算相当于slice(3,4)
console.log(newArr);                //[45]
var newArr2 = arr.slice(-3,-4);     //slice(3,2)
console.log(newArr2);               //[]
  • splice(): slice 是截取数组,而splice是向数组中插入元素或者删除元素,或者替换元素,参数的个数的不同起到的作用也不同。

    1. 删除元素,两个参数,第一个是起始位置,第二个是要删除的个数。此方法会改变原数组,返回值是删除的新数组,不改变原数组。
  var arr = [1,2,3,4,5,6,7,8];
  var item = arr.splice(3,3);
  console.log(item);            //[4, 5, 6]
  console.log(arr);         //(6) [1, 2, 3, 7, 8]

2.插入元素,三个参数,第一个参数是起始位置,第二个参数删除的个数为0,第三个是要插入的元素,如果要插入多个项,则会有第四个,五个参数,总之,从第三个开始都是要插入的项数,返回值是[],会改变原数组。

var arr = [1,2,3,4,5,6,7,8];
var item = arr.splice(4,0,\"xiaomage\");
console.log(arr);       //(9) [1, 2, 3, 4, \"xiaomage\", 5, 6, 7, 8]                  
console.log(item);      //[]
var item2 = arr.splice(5,0,[10,23,45],\"js\",\"web\");
console.log(arr);       //(12) [1, 2, 3, 4, \"xiaomage\",[10,23,45], \"js\", \"web\", 5, 6, 7, 8]
console.log(item2);     //[]
  1. 替换元素,三个以上的参数,其中第二个参数不能为0,否则就是插入元素了,先删除后替换。返回值是删除原数组的元素所组成的数组
var arr = [1,2,3,4,5,6,7,8];
var item = arr.splice(3,2,100000,10000001,10002);
console.log(arr);           //(9) [1, 2, 3, 100000, 10000001, 10002, 6, 7, 8]
console.log(item);          // [4, 5]

分析一下,首先是从第三个开始删除了两项,得到[4,5],然后再在此位置上插入了三项,删除项和替换项不一定要相等。

9. 查找位置相关的方法

javascript数组提供查找位置的方法有两种,indexOf()和lastIndexOf(). 查找的时候当数组中有重复的元素是只返回首次出现的元素的位置。

  1. indexOf(): 如果在数组中能查找到则返回其索引值,如果找不到则返回-1。此方法接受两个参数,第一个参数是要查找的元素,第二个参数是查找的起始位置, 如果没有第二个参数则默认从0开始查, 如果第二个参数是负数的话,则将其作为数组末尾值得一个抵消,即-1表示从最后一个元素开始向后查找,-2表示从倒数第二个元素查找。 如果第二个参数大于数组的长度,表示 已经超出查找范围了,直接返回-1。一直都是从前向后查找,跟参数是不是 负数,查出范围没关系,此方法不会改变原数组。
  2. lastIndexOf(): 与indexOf()不同的是这个方法是从后向前查找,其他的都一样。
var arr =  [1, 2, 3, 100000, 10000001,[34,45],6,3 ,10002, 6, 7, 8];
var count = arr.indexOf(6);     
var count5 = arr.indexOf(6,100);
var count1 = arr.indexOf([34,45]);
console.log(count);                     //6
console.log(count5)                     //-1
console.log(count1);                    //-1
var count2 = arr.indexOf(\"xiaoamge\");
console.log(count2);                    //-1
var count3  = arr.lastIndexOf(3);
console.log(count3);                    //7
var count4 = arr.lastIndexOf([34.45]);
console.log(count4);                    //-1

10.数组的迭代方法

数组的迭代在ES5中是有5个,分别是every,filter,forEach,map,some,这五个方法接受两个参数,第一个是函数,是要作用在数组的每一项上面的函数,第二个参数是作用域对象,可选,默认是this即数组对象本身。第一个参数函数接受三个参数,分别是数组的每一项,第二个是索引,第三个是当前的数组。下面分别来看一下其含义和用法:

  • every() : 英文意思,简单理解是每一个,即作用在数组每一项上面的函数的返回都为true的时候,Array.every才返回true,此方法不会改变原数组。看一个例子,有一个学生的成绩数组,判断是不是都及格了,看看怎么写:
var arr = [99,57,67,88,100,78];
var result = arr.every(function(item, index ,array){
    return item > 60 ;
});
console.log(result);            //false
console.log(arr);               //[99,57,67,88,100.78]

var arr2 = [100,98,87,76,61];
var result2 = arr2.every(function(item, index , array){
    return item >60 ;
});
console.log(result2);           //true
  • filter() : 过滤,即把符合指定条件的过滤出来,比较简单,看看例子,把及格的学生筛选出来:
var arr = [99,57,67,88,60,100,78];
var newArr = arr.filter(function(item , index ,array){
    return item >= 60 ;
});
console.log(newArr);            //[99, 67, 88, 60,100, 78]
  • forEach() : 遍历数组的每一项然后进行后续的逻辑操作 , 此方法没有返回值。
var arr = [99,57,67,88,60,100,78] ;
var newArr = [] ;
arr.forEach(function(item , index ,array){
    if(item >=60){
        newArr.push(\'及格\') ;
    }else {
        newArr.push(\'不及格\') ;
    };
});
console.log(newArr);            //[\"及格\", \"不及格\", \"及格\", \"及格\", \"及格\", \"及格\", \"及格\"]
  • map() : 遍历整个数组的每一项,返回指定操作后的结果。
var arr = [99,57,67,88,60,100,78] ;
var newArr = arr.map(function(item , index ,array){
    //return item * 10 +10 ;        //[1000, 580, 680, 890, 610, 1010, 790]
    return item>=60 ? \'及格\' : \'不及格\' ;
});
console.log(newArr) ;           //[\"及格\", \"不及格\", \"及格\", \"及格\", \"及格\", \"及格\", \"及格\"]
  • some() :此方法跟every()不同的是,every只有都满足条件的时候才返回true ,some是只要有一个满足条件就返回true。every 类似于 && ,而some 类似于 ||。看个例子,查看班级里面有没有成绩超过90分的同学,并且计算有几个:
var arr = [45, 60 , 80, 90 ,99 ,94];
var count = 0 ;
var result = arr.some(function(item , index , array){
   return item >90 ; 
});
console.log(result) ;       //true

var count = arr.filter(function(item , index ,array){
    return item >=90;
}).length;
                       
console.log(count) ;        //3

11.数组的缩小方法

ES5中提供了两个数组缩小的方法,reduce()和reduceRight(), 两个方法都会遍历数组的所有项,然后返回一个操作后的最终结果。这两个方法都接受两个参数,第一个,作用在数组项上的函数,第二个,是 作为缩小基础的初始值,可选。

  • reduce() : 接受四个参数,分别是前一个值(prev),当前值(cur),索引 (index),以及当前数组本身(array),参数名字随便起。当reduce的第二参数有值的时候,第一次遍历的时候,函数的的第一个参数(prev)就是这个初始值,没有值时,第一次遍历的时候前一个值(prev)和当前值(cur)分别是数组的前两项。有点斐波那契数列的感觉,遍历的时候是从前向后。来看一个字符串拼接操作应用:
var arr= [\'hello\' ,\'_this\' , \'_is\' , \'_javascript\' ,\'_Array\'];
var result = arr.reduce(function(prev, cur ,index , array ){
    console.log(prev , cur) ;
    // xiomage_  hello
    // xiomage_hello  _this
    // xiomage_hello_this  _is
    // xiomage_hello_this_is  _javascript
    // xiomage_hello_this_is_javascript  _Array
    return prev + cur ;
},\'xiomage_\');
console.log(result);        //xiomage_hello_this_is_javascript_Array
  • reduceRight() : 和reduce唯一不同的是从后向前遍历,类似于indexof和lastIndexOf()的查找顺序,一个前面开始,一个从后面开始。
var arr = [1,2,3,4,5,6];
var result = arr.reduceRight(function(prev,cur,index,array){
    return prev + cur ;
});
console.log(result);            //21

好了,ES5数组的所有的方法已经讲完了,总共9大类,23个函数,你都了解了吗?

下一篇文章,我会讲述ES6中对数组的加成,新增了哪些方法,以及定型数组,类数组和类数组的所有方法,记得关注哦!

人已赞赏
随笔日记

一图看懂72家科创板受理公司:拟募资总额超650亿 已有35家公司被问询

2020-11-9 4:22:36

随笔日记

最近话题火爆的四件事你知道不?

2020-11-9 4:22:38

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索