JavaScript数组方法详解

在实际开发中,Array 是除了 Object 最长用的数据类型了。Array 和其他编程语言有些许的差别,JavaScript 中的 Array 每个槽位可以存储任意类型的数据,此外它也是动态大小的,会随着数据的添加而自动增长。今天,就让我们来总结一下吧。

一、创建数组

1、使用 Array 构造函数

无参构造

let arr = new Array(); // 创建一个空数组

带参构造

如果知道数组中元素的数量,那么可以给构造函数传入一个数值,然后 length 属性就会被自动创建并设置为这个值。也可以给 Array 构造函数传入要保存的元素。

let arr1 = new Array(10); // 长度为10的空数组
let arr2 = new Array("Mercury", "www.shanzhonglei.com"); // 创建一个包含2个字符串的数组

注意:使用 Array 构造函数时,可以省略 new 操作符

2、数组字面量

let arr1 = []; //创建一个空数组
let arr2 = [10]; // 创建一个包含1项数据为10的数组
let arr3 = ["Mercury", "www.shanzhonglei.com"]; // 创建一个包含2个字符串的数组

3、Array.from()

Array.from()从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。

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

/*
arrayLike  想要转换成数组的伪数组对象或可迭代对象。
mapFn 可选 如果指定了该参数,新数组中的每个元素会执行该回调函数。
thisArg 可选 可选参数,执行回调函数 mapFn 时 this 对象。
*/

Array.from('shan');  // [ "s", "h", "a", "n" ]

const set = new Set(["Mercury","Venus","Earth"]);
Array.from(set); // ["Mercury","Venus","Earth"]

Array.from([1, 2, 3], x => x + x); // [2, 4, 6]

2、Array.of()

Array.of()用于将一组参数转换为数组实例,而不管参数的数量与类型。

Array.of(element0[, element1[, ...[, elementN]]])

// elementN 任意个参数,将按顺序成为返回数组中的元素。

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

二、检测数组

在只有一个网页的情况,也就是只有一个全局作用域的时候,可以使用 instanceof 操作符。

if (value instanceof Array) {
  // ...
}

如果不确定值是哪个全局执行上下文创建的,可以是用 Array.isArray()

if (Array.isArray(value)) {
  // ...
}

三、迭代器

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

  • keys()返回数组索引的迭代器
  • values()返回数组元素的迭代器
  • entries()返回索引/值对的迭代器
const planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];

// 因为这些方法都返回迭代器,所以可以将它们的内容
// 通过 Array.from()直接转换为数组实例

const aKeys = Array.from(planets.keys());
console.log(aKeys);
// [ 0, 1, 2, 3, 4 ]

const aValues = Array.from(planets.values());
console.log(aValues);
// [ 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter' ]

const aEntries = Array.from(planets.entries());
console.log(aEntries);
/*
[ 0, 'Mercury' ],
[ 1, 'Venus' ],
[ 2, 'Earth' ],
[ 3, 'Mars' ],
[ 4, 'Jupiter' ]
*/

四、复制和填充方法

批量复制方法copyWithin(),以及填充数组方法 fill(),都不会改变数组的大小

fill()方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。

/*
arr.fill(value[, start[, end]])
value 用来填充数组元素的值。
start 可选 起始索引,默认值为0。
end 可选 终止索引,默认值为 this.length。
注意:start和end的范围是包括start,不包括end,应该表示为[start, end)
*/

[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]

copyWithin() 方法用于从数组的指定位置浅拷贝元素到数组的另一个指定位置中。

/*
array.copyWithin(target, start, end)
target 必需 复制到指定目标索引位置
start 可选 元素复制的起始位置
end 可选 停止复制的索引位置 (默认为 array.length)。如果为负值,表示倒数

如果 start 为负,则其指定的索引位置等同于 length+start,length 为数组的长度。end 也是如此
*/

[1, 2, 3, 4, 5].copyWithin(-2) // [1, 2, 3, 1, 2]
[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, 3, 4) // [4, 2, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(-2, -3, -1) // [1, 2, 3, 3, 4]

五、转换方法

所有对象都有 toString()和 valueOf()方法。

  • valueOf() 返回的还是数组本身
  • toString() 返回由数组中每个值的等效字符串拼接而成的一个逗号分隔的字符串。也就是说,对数组的每个值都会调用其 toString()方法,以得到最终的字符串
const planets = ["Mercury", "Venus", "Earth"];
console.log(planets.toString()); // Mercury,Venus,Earth
console.log(planets.valueOf()); // [ 'Mercury', 'Venus', 'Earth' ]

六、栈方法

栈是一种后进先出(LIFO, Last-In-First-Out)的结构,也就是最近添加的项先被删除

数据项的插入(push)和删除(pop)只在栈的一个栈顶发生。

push()方法接收任意数量的参数,并将它们添加到数组末尾,返回数组的最新长度。
pop()方法则用于删除数组的最后一项,同时减少数组的 length 值,返回被删除的项。

let planets1 = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];
let length = planets1.push("Saturn", "Uranus");
console.log(length); // 7
console.log(planets1.toString()); // Mercury,Venus,Earth,Mars,Jupiter,Saturn,Uranus

let planets2 = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];
let planet = planets2.pop();
console.log(planet); // Jupiter
console.log(planets2.toString()); // Mercury,Venus,Earth,Mars

七、队列方法

队列以先进先出(FIFO, First-In-First-Out)形式限制访问。队列在列表末尾添加数据,但从列表开头获取数据。

shift()和 push()组成一组队列方法,unshift()和 pop()组成一组队列方法。

shift()方法把数组的第一个元素删除掉,并且返回所删除的元素。
unshift()在数组前端添加任意项,并返回新数组的长度。

let planets1 = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];
let count = planets1.unshift("Saturn", "Uranus");
console.log(count); // 7
console.log(planets1.toString()); // Saturn,Uranus,Mercury,Venus,Earth,Mars,Jupiter

let planets2 = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];
let planet = planets2.shift();
console.log(planet); // Mercury
console.log(planets2.toString()); // Venus,Earth,Mars,Jupiter

八、排序方法

数组有两个方法可以用来对元素重新排序: reverse()和 sort()。默认情况下, sort()会按照升序重新排列数组元素,即最小的值在前面,最大的值在后面。

sort()方法可以接收一个比较函数,用于判断哪个值应该排在前面。比较函数接收两个参数,如果第一个参数应该排在第二个参数前面,就返回负值;如果两个参数相等,就返回 0;如果第一个参数应该排在第二个参数后面,就返回正值

var digit = [0, 1, 2, 3, 4, 5];
digist.reverse();
console.log(digit); // [ 5, 4, 3, 2, 1, 0 ]

var digist = [5, 13, 24, 20, 0, 10];
console.log(digist.sort()); //[ 0, 10, 13, 20, 24, 5 ]

function compare(num1, num2) {
  if (num1 < num2) {
    return 1;
  } else if (num1 > num2) {
    return -1;
  } else {
    return 0;
  }
}
digist.sort(compare);
console.log(digist); // [ 24, 20, 13, 10, 5, 0 ]

九、操作方法

concat()方法

可以接收多个参数,不会改变原来的数组。

arr1.concat(arr2, arr3, ..., arrX)

slice()方法

不会改变原始数组,返回截取的数组。

array.slice(start, [end]);
// 注意范围,end表示从何处结束选取,不包括end,也就是[start, end)

splice()方法

会改变原始数组,从何处添加/删除元素。

array.splice(index,howmany,item1,.....,itemX)

// index表示从何处添加/删除元素
// howmany应该删除多少元素
// item1,.....,itemX新添加的元素
  • 删除:可以删除任意数量的项,只需指定两个参数,要删除的第一项和要删除的项数。
  • 插入:可以向指定位置插入任意数量的项:只需指定三个参数,起始位置、0(要删除的项数)、要插入的项。
  • 替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定三个参数,起始位置、要删除的项数和要插入的任意数量的项。
// concat()
var digist1 = [1, 2, 3];
var digist2 = [4, 5, 6];
console.log(digist1.concat(digist2)); // [ 1, 2, 3, 4, 5, 6 ]

// splice(),不会改变原始数组!!!
// 提取元素
var planets1 = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];
var planetArr1 = planets1.slice(1, 3);
console.log(planetArr1); // [ 'Venus', 'Earth' ], 截取了下标1(包括)到下标3(不包括)的元素
console.log(planets1); // [ 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter' ],原始数组没有改变

// splice(),会改变原始数组!
//删除
var planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];
var removed = planets.splice(0, 1);
console.log(planets); // [ 'Venus', 'Earth', 'Mars', 'Jupiter' ]
console.log(removed); // [ 'Mercury' ]
//插入
var planets2 = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];
var removed2 = planets2.splice(1, 0, "Saturn", "Uranus");
console.log(removed2); // []
console.log(planets2); // [ 'Mercury','Saturn','Uranus','Venus','Earth','Mars','Jupiter' ]
//替换
var planets2 = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"];
var removed2 = planets2.splice(1, 1, "Saturn", "Uranus");
console.log(removed2); // [ 'Venus' ]
console.log(planets2); // [ 'Mercury', 'Saturn', 'Uranus', 'Earth', 'Mars', 'Jupiter' ]

十、搜索和位置方法

包含 indexOf()、 lastIndexOf()和 includes()。

indexOf()和 lastIndexOf()都返回要查找的元素在数组中的位置,如果没找到则返回-1,includes()返回布尔值。

let nums = [1, 2, 4, 6, 3, 8, 4, 7, 9, 6];

console.log(nums.indexOf(4)); // 2
console.log(nums.lastIndexOf(4)); // 6
console.log(nums.includes(6)); // true

十一、迭代方法

  • every(): 对数组每一项都运行传入的函数,如果对每一项函数都返回 true, 则这个方法返回 true。
  • filter():对数组每一项都运行传入的函数,函数返回 true 的项会组成数组之后返回。
  • forEach():对数组每一项都运行传入的函数,没有返回值。
  • map():对数组每一项都运行传入的函数,返回由每次函数调用的结果构成的数组。
  • some():对数组每一项都运行传入的函数,如果有一项函数返回 true,则这个方法返回 true。

注意,这些方法都不改变调用它们的数组!

// every()
var digist1=[1,2,3,4,5,6];
var everyDigist=digist1.every(function(currentValue,index,arr){
    return (currentValue>5);
});
console.log(everyDigist);  //false

//filter()
var digist2=[1,2,3,4,5,6];
var filterRestult=digist2.filter(function(currentValue,index,arr){
    return (currentValue>4);
});
console.log(filterRestult); //[ 5, 6 ]

// forEach()
var digist3=[5,6];
digist3.forEach(function(currentValue,index,arr){
    console.log(currentValue+"_"+index+"_"+arr);
    //5_0_5,6
    //6_1_5,6
});

// map() 
var digist=[1,2,3,4,5,6]; 
var mapResult=digist.map(function(currentValue,index,arr){
    return currentValue-1;
});
console.log(mapResult); //[ 0, 1, 2, 3, 4, 5 ] // some()
var digist=[1,2,3,4,5,6];
var someResult=digist.some(function(currentValue,index,arr){
    return (currentValue>5);
});
console.log(someResult); //true

十二、归并方法

reduce()

对数组中的所有元素调用指定的回调函数。该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供,对于空数组是不会执行回调函数的。

reduceRight()方法的功能和reduce()功能是一样的,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加。

var values = [5,6,9,8,4,6];
var sum = values.reduce(function(prev,cur,index,array){
    return prev+cur;
},10);
console.log(sum);  //48

最后

欢迎关注我的公众号【前端技术驿站】,多多交流,共同进步!
回复react:
1、React.js大众点评案例完整版
2、React+TypeScript高仿AntDesign开发企业级UI组件库
3、React17+React Hook+TS4最佳实践 仿Jira企业级项目
回复vue
1、[全栈开发 ]Vue+Django REST framework 打造生鲜电商项目
2、核心源码内参
3、Vue3+ElementPlus+Koa2 全栈开发后台系统
4、ES6零基础教学解析彩票
5、Node.js+Koa2框架生态实战 - 从零模拟新浪微博(完整版)
6、vue无人点餐收银系统
回复node
1、Nodejs视频教程
2、全栈最后一公里 - Nodejs 项目的线上服务器部署与发布
3、深入浅出Node.js

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念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

推荐阅读更多精彩内容