文章目录

  • 一.创建数组对象
  • 方式一:使用字面量创建数组
  • 方式二:使用构造函数创建数组
  • Array.of
  • 二.数组中的元素的类型
  • 三.数组的常见方法
  • 1.数组的类型相关
  • Array.from():将伪数组转换为真数组
  • Array.of():创建数组
  • 2.数组元素的添加和删除
  • slice()
  • splice()
  • fill()
  • 3.数组的合并和拆分
  • concat()
  • join()
  • split()
  • copyWithin()
  • 4.数组排序
  • reverse()
  • sort()方法
  • 5.查找数组的元素
  • indexOf() 和 lastIndexOf():获取数据的索引
  • includes()
  • find()
  • findIndex()
  • every()
  • some()
  • 6.遍历数组
  • for/in
  • for/of
  • forEach() 遍历
  • forEach() 能不能改变原数组?
  • map()方法
  • map() 方法会改变原数组吗?
  • filter()
  • reduce()方法
  • reduce() 的常见应用



数组(Array)是属于

内置对象

一.创建数组对象

方式一:使用字面量创建数组

举例:

var arr1 = []; // 创建一个空的数组

var arr2 = [1, 2, 3]; // 创建带初始值的数组
方式二:使用构造函数创建数组

语法:

let arr = new Array(参数);

let arr = Array(参数);

如果参数为空,则表示创建一个空数组;如果参数是一个数值时,表示数组的长度;如果有多个参数时,表示数组中的元素。

举例:

// 方式一
var arr1 = [11, 12, 13];

// 方式二
var arr2 = new Array(); // 参数为空
var arr3 = new Array(4); // 参数为一个数值
var arr4 = new Array(15, 16, 17); // 参数为多个数值

console.log(typeof arr1); // 打印结果:object

console.log('arr1 = ' + JSON.stringify(arr1));
console.log('arr2 = ' + JSON.stringify(arr2));
console.log('arr3 = ' + JSON.stringify(arr3));
console.log('arr4 = ' + JSON.stringify(arr4));

打印结果:

object;

arr1 = [11, 12, 13];
arr2 = [];
arr3 = [null, null, null, null];
arr4 = [15, 16, 17];
Array.of

使用Array.ofnew Array 不同是设置一个参数时不会创建空元素数组

let arr = Array.of(3);
console.log(hd); //[3]

arr = Array.of(1, 2, 3);
console.log(hd); //[1, 2, 3]

二.数组中的元素的类型

数组中可以存放任意类型的数据,例如字符串、数字、布尔值、对象等。

比如:

const arr = ['qianguyihao', 28, true, { name: 'qianguyihao' }];

还可以存放多维数组(数组里面放数组)。比如:

const arr2 = [
    [11, 12, 13],
    [21, 22, 23],
];

三.数组的常见方法

1.数组的类型相关

方法

描述

备注

Array.isArray()

判断是否为数组

toString()、String()

将数组转换为字符串

Array.from(arrayLike)

伪数组转化为真数组

Array.of(value1, value2, value3)

创建数组:将一系列值转换成数组

注意,获取数组的长度是用length属性,不是方法。

举例:

//isArray()
//布尔值 = Array.isArray(被检测的数组);
let arr1=[1,2,5];
console.log(Array.isArray(arr1));//true

//toString():数组转换为字符串
//字符串 = 数组.toString();
//解释:把数组转换成字符串,每一项用,分割。注:大多数的数据类型都可以使用.toString()方法,将其转换为字符串。
let str=arr1.toString();
console.log(str);//1,2,5
console.log(String(str));

补充:将数组转换为字符串,有哪些方式

方式1:

字符串 = 数组.toString();

方式 2:

字符串 = String(数组);

方式 3:

字符串 = 数组.join(','); // 将数组转为字符串,每一项用 英文逗号 分隔
console.log([1, 2, 3].join("-"));//1-2-3
Array.from():将伪数组转换为真数组

语法

array = Array.from(arrayLike);

作用:将伪数组或可遍历对象转换为真数组

代码举例:

let name="xiaofeixiaPan";
console.log(Array.from(name));
//(13) ['x', 'i', 'a', 'o', 'f', 'e', 'i', 'x', 'i', 'a', 'P', 'a', 'n']

注:伪数组与真数组的区别

伪数组:包含 length 属性的对象或可迭代的对象。

另外,伪数组的原型链中没有 Array.prototype,而真数组的原型链中有 Array.prototype。因此伪数组没有数组的一般方法,比如 pop()、join() 等方法。

Array.of():创建数组

语法

Array.of(value1, value2, value3);

作用:根据参数里的内容,创建数组。

举例

const arr = Array.of(1, 'abc', true);
console.log(arr); // 打印结果是数组:[1, "abc", true]

注:new Array()Array.of()的区别在于:当参数只有一个时,前者表示数组的长度,后者表示数组中的内容。

2.数组元素的添加和删除

方法

描述

备注

push()

向数组的最后面插入一个或多个元素,返回结果为新数组的长度

会改变原数组

pop()

删除数组中的最后一个元素,返回结果为被删除的元素

会改变原数组

unshift()

在数组最前面插入一个或多个元素,返回结果为新数组的长度

会改变原数组

shift()

删除数组中的第一个元素,返回结果为被删除的元素

会改变原数组

slice()

从数组中提取指定的一个或多个元素,返回结果为新的数组

不会改变原数组

splice()

从数组中删除指定的一个或多个元素,返回结果为被删除元素组成的新数组

会改变原数组

fill()

填充数组:用固定的值填充数组,返回结果为新的数组

会改变原数组

举例:

//push()
let arr2=[1,2,3];
let result1=arr2.push(5);
let result2=arr2.push(7,0);

console.log(result1);//4
console.log(result2);//6
console.log(JSON.stringify(arr2));//[1,2,3,5,7,0]

//pop()
let result3=arr2.pop();
console.log(result3);//0 (返回结果为被删除的元素)

//unshift()
let result4=arr2.unshift("hello","world");
console.log(result4);//7
console.log(JSON.stringify(arr2));//["hello","world",1,2,3,5,7]

//shift()
let result5=arr2.shift();
console.log(result5);//hello
console.log(JSON.stringify(arr2));//["world",1,2,3,5,7]
slice()

从数组中提取指定的一个或者多个元素,返回结果为新的数组(不会改变原来的数组)。

备注:该方法不会改变原数组,而是将截取到的元素封装到一个新数组中返回。

语法

新数组 = 原数组.slice(开始位置的索引, 结束位置的索引); //注意:包含开始索引,不包含结束索引

这里的索引是从下标为0开始

举例:

const arr = ['a', 'b', 'c', 'd', 'e', 'f'];

const result1 = arr.slice(); // 不加参数时,则获取所有的元素。相当于数组的整体赋值
const result2 = arr.slice(2); // 从第二个值开始提取,直到末尾
const result3 = arr.slice(-2); // 提取最后两个元素
const result4 = arr.slice(2, 4); // 提取从第二个到第四个之间的元素(不包括第四个元素)
const result5 = arr.slice(4, 2); // 空

console.log('arr:' + JSON.stringify(arr));
console.log('result1:' + JSON.stringify(result1));
console.log('result2:' + JSON.stringify(result2));
console.log('result3:' + JSON.stringify(result3));
console.log('result4:' + JSON.stringify(result4));
console.log('result5:' + JSON.stringify(result5));

打印结果:

arr: ['a', 'b', 'c', 'd', 'e', 'f'];
result1: ['a', 'b', 'c', 'd', 'e', 'f'];
result2: ['c', 'd', 'e', 'f'];
result3: ['e', 'f'];
result4: ['c', 'd'];
result5: [];
splice()

splice():从数组中删除指定的一个或多个元素,返回结果为被删除元素组成的新数组(会改变原来的数组)。

备注:该方法会改变原数组,会将指定元素从原数组中删除;被删除的元素会封装到一个新的数组中返回。

语法:

新数组 = 原数组.splice(起始索引index, 需要删除的个数);

新数组 = 原数组.splice(起始索引index, 需要删除的个数, 新的元素1, 新的元素2...);

上方语法中,第三个及之后的参数,表示:删除元素之后,向原数组中添加新的元素,这些元素将会自动插入到起始位置索引的前面。也可以理解成:删除了哪些元素,就在那些元素的所在位置补充新的内容。

举例 1:

var arr1 = ['a', 'b', 'c', 'd', 'e', 'f'];
var result1 = arr1.splice(1); //从第index为1的位置开始,删除元素,删到末尾

console.log('arr1:' + JSON.stringify(arr1));
console.log('result1:' + JSON.stringify(result1));

打印结果:

arr1:["a"]
    result1:["b","c","d","e","f"]

举例 2:

var arr2 = ['a', 'b', 'c', 'd', 'e', 'f'];
var result2 = arr2.splice(-2); //删除最后两个元素

console.log('arr2:' + JSON.stringify(arr2));
console.log('result2:' + JSON.stringify(result2));

打印结果:

arr2:["a","b","c","d"]
    result2:["e","f"]

举例 3:

var arr3 = ['a', 'b', 'c', 'd', 'e', 'f'];
var result3 = arr3.splice(1, 3); //从第index为1的位置开始删除元素,一共删除三个元素

console.log('arr3:' + JSON.stringify(arr3));
console.log('result3:' + JSON.stringify(result3));

打印结果:

arr3:["a","e","f"]
    result3:["b","c","d"]

举例4:(删除指定元素)

const arr4 = ['a', 'b', 'c', 'd'];
arr4.splice(arr4.indexOf('c'), 1); // 删除数组中的'c'这个元素

console.log('arr4:' + JSON.stringify(arr4));

举例 5:(第三个参数的用法)

var arr5 = ['a', 'b', 'c', 'd', 'e', 'f'];

//从第index为1的位置开始删除元素,一共删除三个元素。并且在 index=1 的前面追加两个元素
var result5 = arr5.splice(1, 3, 'xiaofeixia', 'Pan');

console.log('arr5' + JSON.stringify(arr5));
console.log('result4:' + JSON.stringify(result5));

打印结果:

arr5["a","xiaofeixia","Pan","e","f"]
result5["b","c","d"]
fill()

用一个固定值填充数组,返回结果为新的数组。会改变原数组。

语法:

// 用一个固定值填充数组。数组里的每个元素都会被这个固定值填充
新数组 = 数组.fill(固定值);

// 从 startIndex 开始的数组元素,用固定值填充
新数组 = 数组.fill(固定值, startIndex);

// 从 startIndex 到 endIndex 之间的元素(包左不包右),用固定值填充
新数组 = 数组.fill(固定值, startIndex, endIndex);

举例1:

// 创建一个长度为4的空数组,然后用 'f' 来填充这个空数组
console.log(Array(4).fill('f')); // ['f', 'f', 'f,' 'f']

// 将现有数组的每一个元素都进行填充
console.log(['a', 'b', 'c', 'd'].fill('f')); // ['f', 'f', 'f,' 'f']

举例2:

// 指定位置进行填充
let arr1 = ['a', 'b', 'c', 'd'];
let arr2 = arr1.fill('f', 1, 3);

console.log(arr1); // ['a', 'f', 'f,' 'd']
console.log(arr2); // ['a', 'f', 'f,' 'd']
3.数组的合并和拆分

方法

描述

备注

concat()

合并数组:连接两个或多个数组,返回结果为新的数组

不会改变原数组

join()

将数组转换为字符串,返回结果为转换后的字符串

不会改变原数组

split()

将字符串按照指定的分隔符,组装为数组

不会改变原字符串

copyWith()

从数组中复制一部分到同数组中的另外位置

会改变原数组

注意,split()是字符串的方法,不是数组的方法。

concat()

concat():连接两个或多个数组,返回结果为新的数组。不会改变原数组。concat()方法的作用是数组合并

语法:

新数组 = 数组1.concat(数组2, 数组3 ...);

举例:

const arr1 = [1, 2, 3];
const arr2 = ['a', 'b', 'c'];
const arr3 = ['xiaofeixia', 'Pan'];

const result1 = arr1.concat(arr2);

const result2 = arr2.concat(arr1, arr3);

console.log('arr1 =' + JSON.stringify(arr1));
console.log('arr2 =' + JSON.stringify(arr2));
console.log('arr3 =' + JSON.stringify(arr3));

console.log('result1 =' + JSON.stringify(result1));
console.log('result2 =' + JSON.stringify(result2));

打印结果:

arr1 =[1,2,3]
arr2 =["a","b","c"]
arr3 =["xiaofeixia","Pan"]

result1 =[1,2,3,"a","b","c"]
result2 =["a","b","c",1,2,3,"xiaofeixia","Pan"]

数组合并的另一种方式

我们可以使用...这种展开语法,将两个数组进行合并。举例如下:

const arr1 = [1, 2, 3];

const result = ['a', 'b', 'c', ...arr1];
console.log(JSON.stringify(result)); // 打印结果:["a","b","c",1,2,3]
join()

join():将数组转换为字符串,返回结果为转换后的字符串(不会改变原来的数组)。

补充:join()方法可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符;如果不指定连接符,则默认使用 , 作为连接符,此时和 toString()的效果是一致的

语法:

新的字符串 = 原数组.join(参数); // 参数选填

代码举例:

var arr = ['a', 'b', 'c'];

var result1 = arr.join(); // 这里没有指定连接符,所以默认使用 , 作为连接符

var result2 = arr.join('-'); // 使用指定的字符串作为连接符

console.log(typeof arr); // 打印结果:object
console.log(typeof result1); // 打印结果:string

console.log('arr =' + JSON.stringify(arr));
console.log('result1 =' + JSON.stringify(result1));
console.log('result2 =' + JSON.stringify(result2));

上方代码中,最后三行的打印结果是:

arr =["a","b","c"]
result1 =a,b,c
result2 =a-b-c
split()

注意,split()是字符串的方法,不是数组的方法。

语法:

新的数组 = str.split(分隔符);

解释:通过指定的分隔符,将一个字符串拆分成一个数组。不会改变原字符串。

let str2="h,e,l,l,o";
let arr5=str2.split(',');
console.log(arr5);//(5) ['h', 'e', 'l', 'l', 'o']
copyWithin()

使用 copyWithin 从数组中复制一部分到同数组中的另外位置。

语法说明

array.copyWithin(target, start, end)

参数说明

参数

描述

target

必需。复制到指定目标索引位置。

start

可选。元素复制的起始位置。

end

可选。停止复制的索引位置 (默认为 array.length)。如果为负值,表示倒数。

const arr = [1, 2, 3, 4];
console.log(arr.copyWithin(2, 0, 2)); //[1, 2, 1, 2]
console.log(arr);//(4) [1, 2, 1, 2]
4.数组排序

方法

描述

备注

reverse()

反转数组,返回结果为反转后的数组

会改变原数组

sort()

对数组的元素,默认按照Unicode 编码,从小到大进行排序

会改变原数组

reverse()

reverse():反转数组,返回结果为反转后的数组(会改变原来的数组)。

语法:

反转后的数组 = 数组.reverse();

举例:

var arr = ['a', 'b', 'c', 'd', 'e', 'f'];

var result = arr.reverse(); // 将数组 arr 进行反转

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));

打印结果:

arr =["f","e","d","c","b","a"]
result =["f","e","d","c","b","a"]
sort()方法

1.sort()方法:无参时

如果在使用 sort() 方法时不带参,则默认按照Unicode 编码,从小到大进行排序。

举例 1:(当数组中的元素为字符串时)

let arr1 = ['e', 'b', 'd', 'a', 'f', 'c'];

let result = arr1.sort(); // 将数组 arr1 进行排序

console.log('arr1 =' + JSON.stringify(arr1));
console.log('result =' + JSON.stringify(result));

打印结果:

arr1 =["a","b","c","d","e","f"]
    result =["a","b","c","d","e","f"]

举例 2:(当数组中的元素为数字时)

let arr2 = [5, 2, 11, 3, 4, 1];

let result = arr2.sort(); // 将数组 arr2 进行排序

console.log('arr2 =' + JSON.stringify(arr2));
console.log('result =' + JSON.stringify(result));

打印结果:

arr2 =[1,11,2,3,4,5]
result =[1,11,2,3,4,5]

使用 sort() 排序后,数字11竟然在数字2的前面。

原因:sort()方法是按照Unicode 编码进行排序的。

2.sort()方法:带参时,自定义排序规则

如果在 sort()方法中带参,可以自定义排序规则。具体做法如下:

可以在 sort()添加一个回调函数,来指定排序规则。回调函数中需要定义两个形参,浏览器将会分别使用数组中的元素作为实参去调用回调函数。

浏览器根据回调函数的返回值来决定元素的排序:(重要)

  • 如果返回一个大于 0 的值,则元素会交换位置
  • 如果返回一个小于 0 的值,则元素位置不变
  • 如果返回一个等于 0 的值,则认为两个元素相等,则不交换位置

写法 1

var arr = [5, 2, 11, 3, 4, 1];

// 自定义排序规则
var result = arr.sort(function (a, b) {
    if (a > b) {
        // 如果 a 大于 b,则交换 a 和 b 的位置
        return 1;
    } else if (a < b) {
        // 如果 a 小于 b,则位置不变
        return -1;
    } else {
        // 如果 a 等于 b,则位置不变
        return 0;
    }
});

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));

打印结果:

arr = [1, 2, 3, 4, 5, 11];
result = [1, 2, 3, 4, 5, 11];

写法 2:(冒泡排序)

let arr = [5, 2, 11, 3, 4, 1];

// 自定义排序规则
let result = arr.sort(function (a, b) {
    return a - b; // 升序排列
    // return b - a; // 降序排列
});

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));

打印结果不变。

写法 3:(箭头函数)

let arr = [5, 2, 11, 3, 4, 1];

// 自定义排序规则
let result = arr.sort((a, b) => {
    return a - b; // 升序排列
});

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));

写法 4:(推荐)

let arr = [5, 2, 11, 3, 4, 1];

// 自定义排序规则:升序排列
let result = arr.sort((a, b) => a - b);

console.log('arr =' + JSON.stringify(arr));
console.log('result =' + JSON.stringify(result));
5.查找数组的元素

方法

描述

备注

indexOf(value)

从前往后索引,检索一个数组中是否含有指定的元素

lastIndexOf(value)

从后往前索引,检索一个数组中是否含有指定的元素

includes(item)

数组中是否包含指定的内容

find(function())

找出第一个满足「指定条件返回 true」的元素

findIndex(function())

找出第一个满足「指定条件返回 true」的元素的 index

every()

确保数组中的每个元素都满足「指定条件返回 true」,则停止遍历,此方法才返回 true

全真才为真。要求每一项都返回 true,最终的结果才返回 true

some()

数组中只要有一个元素满足「指定条件返回 true」,则停止遍历,此方法就返回 true

一真即真。只要有一项返回 true,最终的结果就返回 true

indexOf() 和 lastIndexOf():获取数据的索引

语法 1

索引值 = 数组.indexOf(想要查询的元素);

索引值 = 数组.lastIndexOf(想要查询的元素);

备注:indexOf() 是从前向后查找元素的位置。同理,lastIndexOf()是从后向前寻找。

解释:可以检索一个数组中是否含有指定的元素。如果数组中含有该元素,则会返回其第一次出现的索引;如果没有找到指定的内容,则返回 -1。

这个方法的作用:

  • 如果获取的索引值为 0,说明数组是以查询的元素为开头的
  • 如果获取的索引值为-1,说明这个数组中没有指定的元素。

注意indexOf()在检索时,是严格类型约束,类似于===

举例 1

var arr = ['a', 'b', 'c', 'd', 'e', 'd', 'c'];

console.log(arr.indexOf('c')); //从前往后,找第一个"c"在哪个位置
console.log(arr.lastIndexOf('d')); //从后往前,找第一个"d"在哪个位置

打印结果:

2
5

举例 2

let arr = ['1', '2', '3', '4', '5'];
console.log(arr.indexOf(2));

打印结果:

-1

语法 2

这个方法还可以指定第二个参数,用来指定查找的起始位置。语法如下:

索引值 = 数组.indexOf(想要查询的元素, [起始位置]);

举例 3:(两个参数时,需要特别注意)

let arr = ['x', 'i', 'a', 'o', 'f', 'e', 'i', 'x', 'i', 'a', 'P','a','n'];
result = arr.indexOf('i', 3); // 从下标为3的位置开始查找 'i'这个元素 

console.log(result); // 打印结果:6
includes()

语法

布尔值 = arr.includes(想要查找的元素, [position]);

解释:判断一个数组中是否包含指定的元素。如果是,则会返回 true;否则返回 false。

参数中的 position:如果不指定,则默认为0;如果指定,则规定了检索的起始位置。

const arr = [11, 12, 13, 14, 15];
console.log(arr.includes(12)); // 打印结果:true
console.log(name.includes(20)); // 打印结果:false

console.log(name.includes(11, 1)); // 打印结果:false
find()

语法

find((item, index,arr) => {
    return true;
});

作用:找出第一个满足「指定条件返回 true」的元素;如果没找到,则返回 undefined。

备注:一旦找到符合条件的第一个元素,将不再继续往下遍历。

举例:

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

let result = arr.find((item, index) => {
    return item > 4; //遍历数组arr,一旦发现有第一个元素大于4,就把这个元素返回
});

console.log(result); //打印结果:5
findIndex()

语法

findIndex((item, index, arr) => {
    return true;
});

作用:找出第一个满足「指定条件返回 true」的元素的 index。

举例:

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

let result = arr.findIndex((item, index) => {
    return item > 4; //遍历数组arr,一旦发现有第一个元素大于4,就把这个元素的index返回
});

console.log(result); //打印结果:3
every()

every():对数组中每一项运行回调函数,如果都返回 true,every 就返回 true;如果有一项返回 false,则停止遍历,此方法返回 false。

注意:every()方法的返回值是 boolean 值,参数是回调函数。

举例:

var arr1 = ['好好', '学习', '天天向上', '张三'];
var bool1 = arr1.every(function (element, index, array) {
    if (element.length > 2) {
        return false;
    }
    return true;
});
console.log(bool1); //输出结果:false。只要有一个元素的长度是超过两个字符的,就返回false

var arr2 = ['好好', '学习', '天天', '向上'];
var bool2 = arr2.every(function (element, index, array) {
    if (element.length > 2) {
        return false;
    }
    return true;
});
console.log(bool2); //输出结果:true。因为每个元素的长度都是两个字符。
some()

some():对数组中每一个元素运行回调函数,只要有一个元素返回 true,则停止遍历,此方法返回 true。

注意:some()方法的返回值是 boolean 值。

6.遍历数组

方法

描述

备注

for 循环

forEach()

和 for 循环类似,但需要兼容 IE8 以上

forEach() 没有返回值。也就是说,它的返回值是 undefined

map()

对原数组中的每一项进行加工,将组成新的数组

不会改变原数组

filter()

过滤数组:返回结果是 true 的项,将组成新的数组,返回结果为新的数组

不会改变原数组

reduce

接收一个函数作为累加器,返回值是回调函数累计处理的结果

for/in、for/of

for/in

遍历时的 key 值为数组的索引

let lessons = [
	{title: '媒体查询响应式布局',category: 'css'},
  {title: 'FLEX 弹性盒模型',category: 'css'},
	{title: 'MYSQL多表查询随意操作',category: 'mysql'}
];

for (const key in lessons) {
    console.log(`标题: ${lessons[key].title}`);
}
/*
标题: 媒体查询响应式布局
标题: FLEX 弹性盒模型
标题: MYSQL多表查询随意操作
*/
for/of

for/in 不同的是 for/of 每次循环取其中的值而不是索引。

let lessons = [
	{title: '媒体查询响应式布局',category: 'css'},
  {title: 'FLEX 弹性盒模型',category: 'css'},
	{title: 'MYSQL多表查询随意操作',category: 'mysql'}
];

for (const item of lessons) {
  console.log(`
    标题: ${item.title}
    栏目: ${item.category == "css" ? "前端" : "数据库"}
  `);
}

遍历数组的方法包括:every()、filter()、forEach()、map()等。

PS:这几个方法不会修改原数组

语法格式:

数组/boolean/无 = 数组.every/filter/forEach/map/some(
                        function(item, index, arr){
                                        程序和返回值;
                        })
forEach() 遍历

forEach() 这种遍历方法只支持 IE8 以上的浏览器。IE8 及以下的浏览器均不支持该方法。

forEach()方法需要一个函数作为参数。这种函数,是由我们创建但是不由我们调用的,我们称为回调函数。

数组中有几个元素,该回调函数就会执行几次。

回调函数中传递三个参数:

  • 第一个参数,就是当前正在遍历的元素
  • 第二个参数,就是当前正在遍历的元素的索引
  • 第三个参数,就是正在遍历的数组

代码举例:

let myArr = ['a', 'b', 'c'];

myArr.forEach((item, index, arr) => {
    console.log('item:' + item);
    console.log('index:' + index);
    console.log('arr:' + JSON.stringify(arr));
    console.log('----------');
});

打印结果:

item:a
index:0
arr:["王一","王二","王三"]
----------
item:b
index:1
arr:["王一","王二","王三"]
----------
item:c
index:2
arr:["王一","王二","王三"]
----------

注意,forEach() 没有返回值。也可以理解成:forEach() 的返回值是 undefined。如果你尝试 tempArry = myArr.forEach()这种方式来接收,是达不到效果的。

forEach() 能不能改变原数组?

1、数组的元素是基本数据类型:(无法改变原数组)

let numArr = [1, 2, 3];

numArr.forEach((item) => {
    item = item * 2;
});
console.log(JSON.stringify(numArr)); // 打印结果:[1, 2, 3]

2、数组的元素是引用数据类型:(直接修改整个元素对象时,无法改变原数组)

let objArr = [
    { name: '张三', age: 20 },
    { name: '李四', age: 30 },
];

objArr.forEach((item) => {
    item = {
        name: '王五',
        age: '29',
    };
});
console.log(JSON.stringify(objArr));
// 打印结果:[{"name":"张三","age":20},{"name":"李四","age":30}]

3、数组的元素是引用数据类型:(修改元素对象里的某个属性时,可以改变原数组)

let objArr = [
    { name: '张三', age: 20},
    { name: '李四', age: 30 },
];

objArr.forEach((item) => {
    item.name = '王五';
});
console.log(JSON.stringify(objArr)); 
// 打印结果:[{"name":"王五","age":20},{"name":"王五","age":30}]

4、forEach() 通过参数 2、参数 3 修改原数组:(标准做法)

// 1、数组的元素是基本数据类型
let numArr = [1, 2, 3];

numArr.forEach((item, index, arr) => {
    arr[index] = arr[index] * 2;
});
console.log(JSON.stringify(numArr)); // 打印结果:[2,4,6]

// 2、数组的元素是引用数据类型时,直接修改对象
let objArr = [
    { name: '张三', age: 28 },
    { name: '李四', age: 34 },
];

objArr.forEach((item, index, arr) => {
    arr[index] = {
        name: '王五',
        age: '10',
    };
});
console.log(JSON.stringify(objArr)); 
// 打印结果:[{"name":"王五","age":"10"},{"name":"王五","age":"10"}]

// 3、数组的元素是引用数据类型时,修改对象的某个属性
let objArr2 = [
    { name: '张三', age: 28 },
    { name: '李四', age: 34 },
];

objArr2.forEach((item, index, arr) => {
    arr[index].name = '王五';
});
console.log(JSON.stringify(objArr2)); 
// 打印结果:[{"name":"王五","age":28},{"name":"王五","age":34}]
map()方法

语法:

arr.map(function (item, index, arr) {
    return newItem;
});

解释:对数组中每一项运行回调函数,返回该函数的结果,组成的新数组(返回的是加工之后的新数组)。不会改变原数组。

作用:对数组中的每一项进行加工。

举例 1:(拷贝的过程中改变数组元素的值)

有一个已知的数组 arr1,我要求让 arr1 中的每个元素的值都加 10,这里就可以用到 map 方法。代码举例:

var arr1 = [1, 3, 6, 2, 5, 6];

var arr2 = arr1.map(function (item, index) {
    return item + 10; //让arr1中的每个元素加10
});
console.log(arr2);//(6) [11, 13, 16, 12, 15, 16]

举例 2:【重要案例,实际开发中经常用到】

将 A 数组中某个属性的值,存储到 B 数组中。

代码举例:

const arr1 = [
    { name: '张三', age: '28' },
    { name: '李四', age: '32' },
];
// 将数组 arr1 中的 name 属性,存储到 数组 arr2 中
const arr2 = arr1.map((item) => item.name);

// 将数组 arr1 中的 name、age这两个属性,改一下“键”的名字,存储到 arr3中
const arr3 = arr1.map((item) => ({
    myName: item.name,
    myAge: item.age,
})); // 将数组 arr1 中的 name 属性,存储到 数组 arr2 中

console.log('arr1:' + JSON.stringify(arr1));
console.log('arr2:' + JSON.stringify(arr2));
console.log('arr3:' + JSON.stringify(arr3));

打印结果:

arr1:[{"name":"张三","age":"28"},{"name":"李四","age":"32"}]

arr2:["张三","李四"]

arr3:[{"myName":"张三","myAge":"28"},{"myName":"李四","myAge":"32"}]
map() 方法会改变原数组吗?

不一定。

const arr = [
        {
          name: "xiaofeixia",
          age: 22,
        },
        {
          name: "Pan",
          age: 23,
        },
      ];

      arr.map((item) => {
        item.name = "haha"; // 修改 item 里的某个属性
        return item;
      });
      console.log(JSON.stringify(arr));

打印结果:

[{"name":"haha","age":22},{"name":"haha","age":23}]

总结:
map方法如果是修改整个item的值,则不会改变原数组,但如果是修改item里某个属性的值,就会改变原数组。

filter()

语法:

arr.filter(function (item, index, arr) {
    return true;
});

解释:对数组中的每一项运行回调函数,该函数返回结果是 true 的项,将组成新的数组(返回值就是这个新的数组)。不会改变原数组。

作用:对数组进行过滤。

举例 1:找出数组 arr1 中大于 4 的元素,返回一个新的数组。代码如下:

let arr1 = [1, 3, 6, 2, 5, 6];

let arr2 = arr1.filter((item) => {
    if (item > 4) {
        return true; // 将arr1中大于4的元素返回,组成新的数组
    }
    return false;
});

console.log(JSON.stringify(arr1)); // 打印结果:[1,3,6,2,5,6]
console.log(JSON.stringify(arr2)); // 打印结果:[6,5,6]

上方代码更简洁的写法如下:

let arr1 = [1, 3, 6, 2, 5, 6];

let arr2 = arr1.filter((item) => item > 4); // 将arr1中大于4的元素返回,组成新的数组

console.log(JSON.stringify(arr1)); // 打印结果:[1,3,6,2,5,6]
console.log(JSON.stringify(arr2)); // 打印结果:[6,5,6]

举例 2

获取数组 A 中指定类型的对象,放到数组 B 中。

代码举例如下:

const arr1 = [
    { name: '张三', type: '男' },
    { name: '李四', type: '女' },
    { name: '王五', type: '男' },
];

const arr2 = arr1.filter((item) => item.type == '男'); // 筛选出男性

console.log(JSON.stringify(arr2));
//[{"name":"张三","type":"男"},{"name":"王五","type":"男"}]
reduce()方法

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。返回值是回调函数累计处理的结果。

语法

arr.reduce(function (previousValue, currentValue, currentIndex, arr) {}, initialValue);

参数解释:

  • previousValue:必填,上一次调用回调函数时的返回值
  • currentValue:必填,当前正在处理的数组元素
  • currentIndex:选填,当前正在处理的数组元素下标
  • arr:选填,调用 reduce()方法的数组
  • initialValue:选填,可选的初始值(作为第一次调用回调函数时传给 previousValue 的值)

在以往的数组方法中,匿名的回调函数里是传三个参数:item、index、arr。但是在 reduce() 方法中,前面多传了一个参数previousValue,这个参数的意思是上一次调用回调函数时的返回值。第一次执行回调函数时,previousValue 没有值怎么办?可以用 initialValue 参数传给它。

举例:

let arr1 = [1, 2, 3, 4, 5, 6];

arr1.reduce((prev, item) => {
    console.log(prev);
    console.log(item);
    console.log('------');
    return 88;
}, 0);

打印结果:

0
1
------
88
2
------
88
3
------
88
4
------
88
5
------
88
6
------

上面的代码中,由于return的是固定值,所以 prev 打印的也是固定值(只有初始值是 0,剩下的遍历中,都是打印 88)。

reduce() 的常见应用

举例 1、求和:

计算数组中所有元素项的总和。代码实现:

const arr = [2, 0, 1, 9, 6];
// 数组求和
const total = arr.reduce((prev, item) => {
    return prev + item;
});

console.log('total:' + total); // 打印结果:18

举例 2、统计某个元素出现的次数:

代码实现:

// 定义方法:统一 value 这个元素在数组 arr 中出现的次数
function repeatCount(arr, value) {
    if (!arr || arr.length == 0) return 0;

    return arr.reduce((totalCount, item) => {
        totalCount += item == value ? 1 : 0;
        return totalCount;
    }, 0);
}

let arr1 = [1, 2, 6, 5, 6, 1, 6];

console.log(repeatCount(arr1, 6)); // 打印结果:3

举例 3、求元素的最大值:

代码实现:

const arr = [2, 0, 1, 9, 6];
// 数组求最大值
const maxValue = arr.reduce((prev, item) => {
    return prev > item ? prev : item;
});

console.log(maxValue); // 打印结果:9