超详细Javascript数组使用

Javascript数组

本文章的目的主要在于方便查阅JavaScript数组的一些方法,可以按需选择阅读。如有书写不当的地方,希望指正。

创建数组

这里提供两种方法创建数组

  1. new Array()

    let test=new Array();
    console.log(test) // []
    

    可以传入参数,如果传入的参数是数值,那么length会被赋值为传入的参数

    	let test=new Array(12);
        console.log(test.length) // 12
        console.log(test) // (12) [empty × 12]
    

    如果传入的参数不只一个,参数都会会作为数组的值存入数组

      let test=new Array(12,'aa','bb','cc');
      console.log(test.length) // 4
      console.log(test) // (4) [12, 'aa', 'bb', 'cc']
    

    当然,new也是可以省略的;

  2. 数组字面量

    数组字面量是在中括号中包含以逗号分隔的元素列表

	    let test1=[1,2,3,4,5];
        let test2=[];
        let test3=['aa','bb',123];
        console.log(test1); // (5) [1, 2, 3, 4, 5]
        console.log(test2); // []
        console.log(test3); // (3) ['aa', 'bb', 123]

类数组转换为数组

ES6新增了两个用于创建数组的静态方法:from()of()

from

  1. from() 是用于将类数组转换成数组实例,第一个参数为类数组对象,如下
let a='I like JavaScript';
console.log(Array.from(a)); // (17) ['I', ' ', 'l', 'i', 'k', 'e', ' ', 'J', 'a', 'v', 'a', 'S', 'c', 'r', 'i', 'p', 't']
  1. from 还能接收第二个映射函数参数,可以直接增强(改变)新数组的值, 如下:
let test="123456";
let result=Array.from(test,function(x){return x*1+2});
console.log(result); //(6) [3, 4, 5, 6, 7, 8]
  1. from 还能接收第三个参数,用来指定映射函数参数中this的值
let test="123456";
let result=Array.from(test,function(x){return x*1+this.three},{three:3});
console.log(result); //(6) [4, 5, 6, 7, 8, 9]

of

of() 是用于将一组参数转换为数组实例, 如下:

function test(){
 /* arguments 是函数收集传入参数的类数组 */
console.log(arguments); // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ]
console.log(Array.of(arguments));// [Arguments(3)]
}
test(1,2,3);

数组空位

使用数组字面量初始化数组时,可以使用一连串的逗号来创建空位。 空位的值为undefined

let test=[,,,,,];
console.log(test.length); // 5
console.log(test) // (5) [empty × 5]
console.log(test[0]===undefined) // true

数组索引

要取得或设置数组的值,需要使用中括号并提供相应值的数字索引.如:

let test=['a','b','c','d'];
console.log(test[1]); // b
// 通过索引修改值
test[1]='e';
console.log(test) // (4) ['a', 'e', 'c', 'd']

在中括号中提供的值表示要访问的值,如果索引小于数组包含的元素数,则返回存储在相应位置的元素。如上test[1]。

如果索引超过数组包含的元素数,数组长度会自动扩展到该索引值+1,用空位补全。

let test=['a','b','c','d'];
test[7]='e';
console.log(test.length); // 8
console.log(test) //  (8) ['a', 'b', 'c', 'd', empty × 3, 'e']

数组的length属性是可读可写的属性,不仅可以通过增加length来增加数组的长度,也可以通过减小length来删除数组元素,将length值设为0为清空数组.

删除元素是从末尾开始删除

let test=['a','b','c','d'];
test.length=9;
console.log(test); // (9) ['a', 'b', 'c', 'd', empty × 5]
test.length=2;
console.log(test); //  ['a', 'b']

迭代器方法

在ES6上,Array的原型上暴露了3个用于检索 数组内容的方法: keys()、values()和entries();

  • keys(): 返回数组索引的迭代器
  • values(): 返回数组元素的迭代器
  • entries(): 返回索引/值 对的迭代器
const test=['a','b','c','d'];
console.log(Array.from(test.keys())); // (4) [0, 1, 2, 3]
console.log(Array.from(test.values())); // (4) ['a', 'b', 'c', 'd']
console.log(Array.from(test.entries())); 
/* 
0: (2) [0, 'a']
1: (2) [1, 'b']
2: (2) [2, 'c']
3: (2) [3, 'd']
 */

在ES6中的解构语法能非常容易的拆分循环中的键值对

const test=['a','b','c','d'];
for(const [key,value] of test.entries()){
    console.log(`${key}:${value}`);
    /*  0:a
        1:b
        2:c
        3:d */
}

复制与填充

ES6新增了两个方法:

  1. 批量复制方法: fill()
  2. 填充数组方法: copyWithin()
  • fill()

该方法可以向一个已有的数组中插入全部或部分相同的值。
第一个参数:指定填充的值
第二个参数:指定开始填充的位置,如果不写,默认全部填充为第一个参数的值
第三个参数:指定填充结束的位置,该位置不填充。

fill()静默忽略超出数组边界、零长度和方向相反的索引范围

let test=[1,2,3,4,5,6];
console.log(test.fill(0)); // (6) [0, 0, 0, 0, 0, 0]
console.log(test.fill(1,2)); // (6) [0, 0, 1, 1, 1, 1]
console.log(test.fill(2,3,5)); // (6) [0, 0, 1, 2, 2, 1]
console.log(test.fill(3,7,9)); // 忽略超出范围 (6) [0, 0, 1, 2, 2, 1]
console.log(test.fill(4,5,1));// 忽略方向相反的 (6) [0, 0, 1, 2, 2, 1]
console.log(test.fill(5,3,3)); // 忽略长度为0的 (6) [0, 0, 1, 2, 2, 1]
  • copyWithin
    该方法会按照指定范围浅复制数组中的部分内容,然后将它们插入到指定索引开始的位置。开始索引和结束索引与fill()使用相同的计算方式

第一个参数:指定插入到索引的位置
第二个参数:指定开始复制的位置,若不写,默认从0开始复制
第三个参数:指定结束复制的位置,

// 重置数组函数
let reset=()=>[1,2,3,4,5,6,7,8,9];
let test=reset();
console.log(test); // (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
console.log(test.copyWithin(5)); // (9) [1, 2, 3, 4, 5, 1, 2, 3, 4]
test=reset();
console.log(test.copyWithin(0,5)); // (9) [6, 7, 8, 9, 5, 6, 7, 8, 9]
test=reset();
console.log(test.copyWithin(0,5,7)); // (9) [6, 7, 3, 4, 5, 6, 7, 8, 9]

转换方法

将数组转换为字符串有如下方法:

  • toString()
  • join()
  1. toString()

该方法返回的是由数组中的每个值的等效字符串拼接而成的一个逗号分隔的字符串

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

该方法返回的是数组本身

let test=[1,2,3,4,5];
let test1=test.valueOf()
console.log(test===test1); //true
  1. join()

该方法内参数为 字符分隔符,如果不写马,默认用 , 分隔

let test=[1,2,3,4,5];
let test1=test.join();
let test2=test.join('-');
let test3=test.join('<>');
console.log(test); // (5) [1, 2, 3, 4, 5]
console.log(test1); // 1,2,3,4,5
console.log(test2); // 1-2-3-4-5
console.log(test3); // 1<>2<>3<>4<>5

注意: 如果数组中某一项是null 或者 undefined,则在 join(), toString(),toLocaleString(),valueOf() 返回的结果会以空字符串表示

let test=[1,2,3,4,5,undefined,null];
let test1=test.join();
let test2=test.join('-');
let test3=test.join('<>');
console.log(test); // [1, 2, 3, 4, 5, undefined, null]
console.log(test1); // 1,2,3,4,5,,
console.log(test2); // 1-2-3-4-5--
console.log(test3); // 1<>2<>3<>4<>5<><>

栈方法

ECMAScript给数组提供了几个方法,让它看起来像是另外一种数据结构——栈。

  1. 数据项的推入: push
    push()方法接收任意数量的参数,将它们添加到数组末尾,并放回数组的最新长度。
let test=[1,2,3];
let len=test.push(4,5,6,7);
console.log(len); // 7
console.log(test);// (7) [1, 2, 3, 4, 5, 6, 7]
  1. 数据项的弹出:pop
    pop()方法删除数组最后一项,同时减少数组的length值,返回被删除的值
let test=[1,2,3];
let len=test.pop();
console.log(len); // 3
console.log(test);// (2) [1, 2]

队列方法

使用shift() 和push,可以将数组当作队列来使用

  1. shift()
    该方法删除数组第一项并将其返回
let test=[1,2,3];
let n=test.shift();
console.log(n); // 1
console.log(test); // (2) [2, 3]
  1. ECMAScript也为数组提供了 unshift()方法
    该方法执行与shift()相反的操作,它可以在数组的开头添加任意数量的元素,并返回数组的长度
let test=[1,2,3];
let n=test.unshift('a','b');
console.log(n); // 5
console.log(test); //(5) ['a', 'b', 1, 2, 3]

排序方法

数组有两个方法可以用来对里面的元素重新排序: reverse()sort

  1. reverse()
    该方法用于将数组里面的元素逆置;
let test=[1,2,3,4,5,6];
let test1=test.reverse();
console.log(test1); // (6) [6, 5, 4, 3, 2, 1]
  1. sort()

默认情况下,该方法会按照升序排列数组元素,为此,sort()会在每一项上会调用转型函数String(),然后比较字符串的决定大小。
但是这就会导致一个问题, 比如 “12”<“5”;

let test=[1,54,12,32,5];
console.log(test.sort()); //(5) [1, 12, 32, 5, 54]

很明显,这样是不合适的,所以sort()方法可以接收一个比较函数,用来判断哪个值一个排在前面。

比较函数接收两个参数,如果第一个参数应该排在第二个参数前面,就返回负值,如果第一个参数应该排在第二个参数后面,就返回正值。

function compare(value1,value2){
    /* 升序比较函数 */
    if(value1>value2) return -1;
    if(value1<value2) return 1;
    else return 0;
}

这个比较函数可以适用大多数数据类型,可以把它作为参数传给sort()方法;

function compare(value1,value2){
    /* 升序比较函数 */
    if(value1>value2) return 1;
    if(value1<value2) return -1;
    else return 0;
}
let arr=[1,2,542,12,5,312];
let arr_1=arr.sort(compare);
console.log(arr_1); // (6) [1, 2, 5, 12, 312, 542]

只要将compare返回值调换一下就能实现降序

此外,如果数组的元素是数值,或者是其valueOf()方法放回数值的对象,这个比较函数还可以写的更简单.

let arr=[1,2,542,12,5,312];
let arr_1=arr.sort(function(a,b){return a-b});
// 比较函数就是要返回小于0,大于0,0的数值,减法完全可以满足要求
console.log(arr_1); // (6) [1, 2, 5, 12, 312, 542]

注意: reverse()和sort()都返回调用它们的数组的引用

操作方法

对于数组中的元素,我们有很多种操作方法,比如concat()、slice()、splice()等

1. concat()

该方法可以在现有数组的全部元素基础上创建一个新数组。它会首先创建一个当前数组的副本,然后把它的参数添加的到副本末尾,最后返回构建的新数组

如果传传入一个或多个数组,concat()会将数组中的每一项添加到副本中,如果参数不是数组,会直接添加到末尾;

let arr=[1,2,3,4,5];
let new_arr=arr.concat(6,7,[8,9],{name:'yihen'});
console.log(new_arr); // (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, {…}]

但是有时候,我们需要加入副本的就是一个数组,而不是将数组的元素一个一个放入副本,这个时候,我们需要重写打平数组参数(简单理解为[…arr])的行为。

方法是在参数数组上指定一个特殊的符号:Symbol.isConcatSpreadable,这个符号能阻止concat()打平参数数组。相反,把这个值设置为true,可以强制打平类数组对象.

强制打平类数组

let test1={
    // 强制打平类数组对象
    [Symbol.isConcatSpreadable]:true,
    0:'a',
    1:'b',
    2:'c',
    length:3
}
let arr=[1,2,3,4];
let new_arr=arr.concat(test1);
console.log(new_arr); // (7) [1, 2, 3, 4, 'a', 'b', 'c']

`不打平参数数组

let arr=[1,2,3,4];
let test1=['a','b','c'];
test1[Symbol.isConcatSpreadable]=false;
let new_arr=arr.concat(test1);
console.log(new_arr); // (5) [1, 2, 3, 4, Array(3)]

2. slice()

该方法创建一个包含原数组的一个或多个元素的新数组。slice()方法可以接收一个或两个参数;
第一个参数: 指定开始截取的索引位置,如果不写,默认截取全部
第二个参数: 指定结束截取的索引位置,但不包括该索引位置,如果不写,默认从开始位置截取的到最后

let arr=[1,2,3,4,5,6];
let new_arr=arr.slice();
let new_arr_2=arr.slice(2);
let new_arr_3=arr.slice(2,4)
console.log(new_arr); // (6) [1, 2, 3, 4, 5, 6]
console.log(new_arr_2); // (4) [3, 4, 5, 6]
console.log(new_arr_3); // (2) [3, 4]

注意:如果slice()的参数有负值,那么就以数组长度+这个负值的结果确定索引的位置。如长度为5的数组,[-2,-1]=>[-2+5,-1+5]=>[3,4],如果开始位置小于结束位置,则返回空数组

3.splice()

该方法的主要目的是在数组中间插入元素,但是有三种不同的方式实现;

  • 删除: 需要给splice()传递两个参数,返回删除元素的数组
    第一个参数:要删除的第一个元素的位置
    第二个参数:要删除的元素数量
let arr=[1,2,3,4,5,6];
let new_arr=arr.splice(1,4);
console.log(new_arr); // (4) [2, 3, 4, 5]
console.log(arr); // (2) [1, 6]
  • 插入:需要给splice()传入三个参数。
    第一个参数:开始删除的位置
    第二个参数: 0,即删除0个
    第三个参数:要插入的元素,该参数后面还可以写要加入的元素的参数
let arr=[1,2,3,4,5,6];
arr.splice(1,0,'a','b');
console.log(arr); // (8) [1, 'a', 'b', 2, 3, 4, 5, 6]
  • 替换: splice()子在删除元素的同时可以在指定位置插入新元素,达到替换效果
let arr=[1,2,3,4,5,6];
arr.splice(1,2,'a','b');
console.log(arr); // (6) [1, 'a', 'b', 4, 5, 6]

搜索和位置方法

ESMAScript提供了两种搜索数组的方法:按严格相等搜索和按断言函数搜索

严格相等

ECMAScript提供了三个严格相等的搜索方法:

  1. indexOf()
  2. lastIndexOf()
  3. includes()

前两个方法在所有版本都可以使用,第三个方法是ES7新增的方法

这些方法都接收两个参数:
第一个参数: 要查找的元素
第二个参数: 开始查找的位置,不写默认从0索引开始

区别:

  • indexOf()和lastIndexOf()返回的是第一个匹配的元素索引,而includes()返回的一个布尔值。
  • indexOf()和includes()都是从指定位置正向开始搜索,lastIndexOf()是从指定位置开始反向搜索.
let arr=[1,2,3,4,5,6,2,3,4];
let index=arr.indexOf(2);
let index_1=arr.indexOf(2,3);
let index_2=arr.lastIndexOf(3);
let index_3=arr.includes(2);
console.log(index); // 1
console.log(index_1);   // 6
console.log(index_2); // 7
console.log(index_3); // true

断言函数

ECMAScript允许按照断言函数搜索数组,每个索引都会调用这个函数。断言函数的返回值决定了相应索引的元素是否被认为匹配。

断言函数接收三个参数:元素,索引,数组本身。其中元素是当前搜索的元素,索引是当前元素的索引,而数组就是正在搜索的数组。

断言函数返回真值表示是否匹配

find()和findIndex()方法使用了断言函数。这两个方法都是从数组的最小索引开始搜索。 find()返回第一个匹配的元素,findIndex()返回第一个匹配的元素索引.

这两个方法也都接收第二个可选参数,用于指定断言函数内部的this值

let arr=[1,2,3,4,5,6,2,3,4];
let index=arr.find(function(item,index,arr){
    // 搜索值为4的元素
    return item==4;
})

let index_1=arr.findIndex(function(item,index,arr){
    // 搜索值为5的元素索引
    return item==5;
})
console.log(index); // 4
console.log(index_1);  // 4

找到匹配项后,这两种方法都不会继续搜索了

迭代方法

ECMAScript为数组定义了5个迭代方法。每个方法接收两个参数:
第一个参数;function(item,index,arr) 与上一个方法相似,item为当前遍历到的元素,index为当前遍历到的索引位置,arr为遍历的数组,都是可选的

第二个参数: 可选,作为影响函数执行上下文的作用域对象(影响this值)

  • every():对数组里面的每一个元素调用函数,如果返回值都是true,最后返回true,否则返回false
  • some():对数组里面的每一个元素调用函数,如果返回值有一个是true,最后返回true,否则返回false
  • fliter():对数组里面的每一个元素调用函数,返回 函数返回值为true的元素
  • forEach():对数组中的每一个元素执行函数,没有返回值
  • map(): 对数组中的每一个元素执行函数,返回由每次函数调用的结果构成的数组

这些方法中,some()和every()是最相似的,从数组中搜索符合条件的元素,但是some()只要由一个符合条件的就返回true,every()只要有一个不符合条件的就返回false

1. every()和some()

let arr=[6,2,3,4,5,6,2,3,4];

// 判断数组元素是否都大于3
let result=arr.every(function(item){
    return item>2;
})

// 判断数组是否有元素大于5
let result_1=arr.some(function(item){
    return item>5
})

console.log(result); // false
console.log(result_1); // true

2. fliter()

fliter()可以用来过滤数组,用来得到符合条件的数组元素

let arr=[6,2,3,4,5,6,2,3,4];
// 现在需要获得数组中所有大于4的元素
let new_arr=arr.filter(function(item){
    return item>4;
})
console.log(new_arr); // (3) [6, 5, 6]

3. map()

map()方法也会接收返回的元素,可以用来处理数组的元素,比如

let arr=[6,2,3,4,5,6,2,3,4];
// 现在需要将所有元素值*2
let new_arr=arr.map(function(item){
    return item*2;
})
console.log(new_arr); // (9) [12, 4, 6, 8, 10, 12, 4, 6, 8]

4. forEach

没有返回值,可以看作是对数组进行了for循环

let arr=[6,2,3,4,5,6,2,3,4];
// 现在需要将所有元素值+2
arr.forEach(function(item,index,arr){
    arr[index]+=2
})
console.log(arr); // (9) [8, 4, 5, 6, 7, 8, 4, 5, 6]

归并方法

ESCAScript为数组提供了两个归并方法:reduce和reduceRight()。
着两个方法都会迭代数组的所有项,并在此基础上构建一个新的返回值。
reduce()方法从数组的第一项开始遍历到最后一项。而reduceRight()从数组的最后一项开始往第一项遍历

这两个方法都接收两个参数:
第一个参数:与上面相同,不过多了一个归并值,function(prev,item,index,arr); 函数每次返回的值会作为下一次执行函数的第一个参数;
第二个参数:归并值prev的起始值,如果不写,默认为数组的第一个值,且函数中的item从数组的第二个元素开始;

let arr=[6,2,3,4,5,6,2,3,4];
// 现在需要统计数组的和
let sum=arr.reduce(function(prev,item){
    console.log(prev);// 没写第二个参数,prev为数组的第一个值
    return prev+item; // item从数组的第二个元素开始
})
console.log(sum); // 35
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

传说中的懿痕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值