1. 1. isArray
  2. 2. .find
  3. 3. .findIndex
  4. 4. .includes
  5. 5. .flat
  6. 6. .sort
  7. 7. .concat
  8. 8. .filter
  9. 9. .map和.forEach
  10. 10. .indexOf和.findIndex
  11. 11. .lastIndexOf
  12. 12. .join
  13. 13. .reduce和.reduceRight
  14. 14. .shift和.pop
  15. 15. .unshift和.push
  16. 16. .some和.every
  17. 17. .slice
  18. 18. .splice
  19. 19. 其他(不常用)
    1. 19.1. from
    2. 19.2. of
    3. 19.3. .copyWithin
    4. 19.4. .fill
    5. 19.5. .entries
    6. 19.6. .keys
    7. 19.7. .values
    8. 19.8. .flatMap
    9. 19.9. .reverse

isArray

  • 检测一个值是否为Array 返回true/false
  • 适用场景: 判断一个值是数组且长度存在
  • 语法Array.isArray(obj)
    • obj 需要检测的值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<!-- 当list为数组且长度存在的时候在进行渲染 -->
<div class="container" v-if="Array.isArray(list) && list.length">
<p v-for="list" :key="item">
{{item}}
</p>
</div>
</template>
<script>
export default {
data() {
return {
list: ['渡远荆门外,来从楚国游。', '山随平野尽,江入大荒流。', '月下飞天镜,云生结海楼。', '仍怜故乡水,万里送行舟。'],
};
},
}
</script>

.find

  • ES6 新增API

  • 从数组中查找第一个符合匹配条件的元素;查找不到返回undefined

  • 实用程度:

  • 适用场景: 从数组中找元素

  • 语法arr.find(callback[, thisArg])

    • callback在数组每一项上执行的函数,接收 3 个参数

      • element 当前遍历到的元素
      • index 当前遍历到的元素下标/索引
      • array 数组本身
    • thisArg 执行回调用做this的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<template>
<!-- element-ui的选择器组件 -->
<el-select v-model="value" placeholder="请选择" @change="handleChange">
<el-option
v-for="item of hospitalList"
:key="item.id"
:label="item.hospitalName"
:value="item.id">
</el-option>
</el-select>
</template>
<script>
import { Select, Option } from 'element-ui';
export default {
components: {
ElSelect: Select,
ElOption: Option,
}
data() {
return {
value: undefined,
hospitalList: [
{
id: 203,
hospitalName: '洛阳市中心医院',
organCode: '661',
provinceCode: '108'
cityCode: '407'
areaCode: '362'
},
{
id: 211,
hospitalName: '北京和协医院',
organCode: '602',
provinceCode: '101'
cityCode: '236'
areaCode: '675'
},
],
form: {
id: undefined,
hospitalName: undefined,
organCode: undefined,
}
};
},
methods: {
handleChange(value) {
// 组件v-model绑定的只是Option的:value,也就是说我们只能拿到医院信息的ID,假设后端需要的数据是“医院ID,医院名,机构Code”,此时最适合find来处理

// try/catch会在之后讲解
// 配合解构赋值
try {
const {id, hospitalName, organCode} = this.hospitalList.find(item => item.id === value);
this.form.id = id, this.form.hospitalName = hospitalName, this.organCode = organCode;
// 这个场景非常适合使用find方法,基本一行代码可以搞定。如果不使用find也许你会字符串拼接到value,再截取,也许会用forEach/for循环便利查找等各种其他操作,但都没有find更方便
// 这里用了try/catch当这里代码执行出错了,会被catch掉 不会阻塞代码运行
} catch(err) {
throw err;
}
}
}
}
</script>

.findIndex

  • ES6 新增API

  • 从数组中查找第一个符合匹配条件的元素的索引;查找不到返回 -1

  • 实用程度:

  • 适用场景: 从数组中找元素索引(更多场景项目中实际发掘吧)

  • findAPI相比:find返回的是符合条件的元素,findIndex返回的是符合条件元素的索引

  • 语法arr.findIndex(callback[, thisArg])

    • callback在数组每一项上执行的函数,接收 3 个参数

      • element 当前遍历到的元素
      • index 当前遍历到的元素下标/索引
      • array 数组本身
    • thisArg 执行回调用做this的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const hospitalList = [
{
id: 203,
hospitalName: '洛阳市中心医院',
organCode: '661',
provinceCode: '108'
cityCode: '407'
areaCode: '362'
},
{
id: 211,
hospitalName: '北京和协医院',
organCode: '602',
provinceCode: '101'
cityCode: '236'
areaCode: '675'
},
];
const idIndex = hospitalList.findIndex(item => item.id === 201); // -1
const organCodeIndex = hospitalList.findIndex(item => item.organCode === '601'); // 1

.includes

  • ES7 新增API

  • 检测数组是否包含指定的元素,返回true/false

  • 实用程度:

  • 适用场景: 订单列表符合条件的订单状态才显示操作按钮

  • 语法arr.includes(valueToFind[, fromIndex])

    • valueToFind要查找的元素值

      includes 对大小写敏感

    • fromIndex 从指定索引处开始查找;默认为0;若为负值,则取绝对值从后往前(从右往左)开始查找

1
2
3
4
5
['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'].includes('d'); // true
['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'].includes('d', 2); // true 从索引为2开始查找
['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'].includes('d', 3); // false 从索引为3开始查找,查找不到false
['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'].includes('d', -3); // true 从右往左倒数索引为-3开始查找(从‘h’开始往左查)
['a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l'].includes('d', 50); // false 从索引50开始查找,数组长度不够,根本找不到 false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<template>
<!-- element-ui的选择器组件 -->
<div class="container">
<div class="order" v-for="item of orderList" :key="item.id">
<!-- 在这里 -->
<button v-if="[3,6,8].includes(item.status)">
分配
</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
orderList: [
{
id: 101909286936,
status: 5,
},
{
id: 101909286976,
status: 6,
},
{
id: 101939286936,
status: 3,
},
{
id: 101909286536,
status: 7,
},
],
};
}
}
</script>

.flat

  • ES10 正式新增
  • 将多维数组进行展开成一维数组
  • 语法const newArray = arr.flat([depth])
    • depth要拉平的数组深度;默认为1
1
2
3
4
5
6
7
8
9
const list = [{name: '李白'}, [{name: '李白'}, {name: '杜甫'}, [str => str, ['唐', '宋', '元', '明', '清']]]];
list.flat(); // [{name: '李白'}, {name: '李白'}, {name: '杜甫'}, [str => str, ['唐', '宋', '元', '明', '清']]];
list.flat(2); // [{name: '李白'}, {name: '李白'}, {name: '杜甫'}, str => str, ['唐', '宋', '元', '明', '清']];

// 如果超过数组本身的深度,那就能拉几层拉几层
list.flat(10); // [{name: '李白'}, {name: '李白'}, {name: '杜甫'}, str => str, '唐', '宋', '元', '明', '清'];

// 如果是负数,就返回数组本身
list.flat(-2); // [{name: '李白'}, [{name: '李白'}, {name: '杜甫'}, [str => str, ['唐', '宋', '元', '明', '清']]]];

.sort

  • 对数组进行排序(官方表述:sort() 方法用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的)

  • 会修改原数组

  • 语法:arr.sort([compareFunction])

    • compareFunction 可选。用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。

      • firstEl 第一个用于比较的元素
      • secondEl 第二个用于比较的元素
    • 返回值: 排序后的数组。请注意,数组已原地排序,并且不进行复制。

如果没有指明 compareFunction ,那么元素会按照转换为的字符串的诸个字符的Unicode位点进行排序。例如 “Banana” 会被排列到 “cherry” 之前。当数字按由小到大排序时,9 出现在 80 之前,但因为(没有指明 compareFunction),比较的数字会先被转换为字符串,所以在Unicode顺序上 “80” 要比 “9” 要靠前。

如果指明了 compareFunction ,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:

  • 如果 compareFunction(a, b) 小于 0 ,那么 a 会被排列到 b 之前;

  • 如果 compareFunction(a, b) 等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本);

  • 如果 compareFunction(a, b) 大于 0 , b 会被排列到 a 之前。

  • compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。

1
2
const hiStory = ['秦','a','1','汉','b',2,'隋','c','3','唐','d',4,'宋',5,'e','元', '6','f','明','g','7',8,'h','清'];
hiStory.sort(); // ["1", 2, "3", 4, 5, "6", "7", 8, "a", "b", "c", "d", "e", "f", "g", "h", "元", "唐", "宋", "明", "汉", "清", "秦", "隋"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const orderList = [
{createTime: 1572944297747, id: 1},
{createTime: 1572944290747, id: 2},
{createTime: 1572944390747, id: 3},
{createTime: 1572944290747, id: 4},
{createTime: 1572944290147, id: 5},
{createTime: 1575944290747, id: 6},
{createTime: 1572943290747, id: 7},
]
orderList.sort((first,second) => first.createTime - second.createTime) // 正序
orderList.sort((first,second) => second.createTime - first.createTime) // 倒序
// 正序
orderList.sort((first,second) => {
if(first.createTime < second.createTime) {
return -1; // a小于b,a排在b之前 返回负数 a排b之前
}
if(first.createTime > second.createTime) {
return 1; // a大于b,b应该排在a之前 返回正数 b在a之前
}
return 0; // 相等,位置不变 返回0
})
// 倒序
// ............不写了

.concat

  • 将多个数组合并为一个
  • 此API是对数组的深拷贝
  • 语法const new_array = old_array.concat(value1[, value2[, ...[, valueN]]])
    • valueN 将数组和/或值连接成新数组。如果省略了valueN参数参数,则concat会返回一个它所调用的已存在的数组的浅拷贝
1
2
const list1 = [{name: '李白'}],list2 = ['陶潜'],other = '窝窝头', school = () => '豫章书院';
const newList = list1.concat(list2,other,school); // [{name: '李白'}, '陶潜', '窝窝头', () => '豫章书院'];

.filter

  • 数组的过滤器;返回符合条件的所有元素

  • 实用程度:

  • 适用场景: 条件查询

  • 语法const newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

    • callback 用来测试数组的每个元素的函数

      • element 数组中当前正在处理的元素。
      • index 可选。正在处理的元素在数组中的索引。
      • array 可选。调用了 filter 的数组本身。
    • thisArg 执行 callback 时,用于 this 的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const orderList = [
{id: 102, content: '数组1', status: 3},
{id: 103, content: '数组2', status: 4},
{id: 104, content: '数组3', status: 3},
{id: 105, content: '数组4', status: 6},
{id: 106, content: '数组5', status: 2},
{id: 107, content: '数组6', status: 4},
{id: 108, content: '数组7', status: 7},
{id: 109, content: '数组8', status: 3},
{id: 110, content: '数组9', status: 8},
{id: 111, content: '数组10', status: 6},
]
const newList = orderList.filter(element => element.status === 3 || element.status === 6); // 查询订单状态是3或者是6的订单

// 输出结果自行CV大法到浏览器终端查看吧

.map和.forEach

  • map()forEach()都是ES5就具有的方法

  • map()forEach()都可以实现对数组的遍历

  • map()会对数组进行深拷贝(官方描述:map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果),forEach()对数组的每一个元素执行一次提供的函数,会修改原数组,无返回值

  • 实用程度:

  • 语法:

    • const new_array = arr.map(callback(currentValue[, index[, array]])[, thisArg])

    • const new_array = arr.forEach(callback(currentValue[, index[, array]])[, thisArg])

      • callback 针对数组中的每个元素, 都会执行该回调函数, 执行时会自动传入下面三个参数:

        • element 数组中当前正在处理的元素。
        • index 可选。正在处理的元素在数组中的索引。
        • array 可选。调用了 此API 的数组本身。
      • thisArg 执行 callback 时,用于 this 的值。

    mapforEach语法一样,没有写错

    注意: 如果使用箭头函数表达式来传入函数参数,thisArg 参数会被忽略,因为箭头函数在词法上绑定了 this 值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
const orderList = [{"contact":"李贺","price":4,"orderStatus":4,"logisticsState":260},{"contact":"袁天罡","price":23.7,"orderStatus":5,"logisticsState":220},{"contact":"袁天罡","price":219.5,"orderStatus":4,"logisticsState":220},{"contact":"苏轼","price":59,"orderStatus":4,"logisticsState":220},{"contact":"秦始皇","price":175.6,"orderStatus":2,"logisticsState":110},{"contact":"孟浩然","price":127.62,"orderStatus":3,"logisticsState":260},{"contact":"苏轼","price":108,"orderStatus":2,"logisticsState":250},{"contact":"李商隐","price":230.8,"orderStatus":4,"logisticsState":220},{"contact":"孟浩然","price":111.3,"orderStatus":4,"logisticsState":110},{"contact":"秦始皇","price":34.8,"orderStatus":3,"logisticsState":260}];

// orderStatus 1 未付款 2 待发货 3 运输中 4 已收货 5 已评价
// logisticsState 110 已接单 220 运输中 140 已揽收 260 配送中 250 已签收
const newOrderList = orderList.map(item => {
item.priceDesc = `${item.price}元`;
if(item.orderStatus === 1) {
item.orderStatusDesc = '未付款';
} else if(item.orderStatus === 2) {
item.orderStatusDesc = '待发货';
} else if(item.orderStatus === 3) {
item.orderStatusDesc = '运输中';
} else if(item.orderStatus === 4) {
item.orderStatusDesc = '已收货';
} else {
item.orderStatusDesc = '已评价';
}
if(item.logisticsState === 110) {
item.logisticsStateDesc = '已接单';
} else if(item.logisticsState === 220) {
item.logisticsStateDesc = '运输中';
} else if(item.logisticsState === 140) {
item.logisticsStateDesc = '已揽收';
} else if(item.logisticsState === 260) {
item.logisticsStateDesc = '配送中';
} else {
item.logisticsStateDesc = '已签收';
}
return item;
});

console.log(newOrderList,orderList); // 自行运行看打印结果,不粘结果了; newOrderList是修改过后的新数组 orderList是原始数组,内容没有改变

orderList.forEach(item => {
item.priceDesc = `${item.price}元`;
if(item.orderStatus === 1) {
item.orderStatusDesc = '未付款';
} else if(item.orderStatus === 2) {
item.orderStatusDesc = '待发货';
} else if(item.orderStatus === 3) {
item.orderStatusDesc = '运输中';
} else if(item.orderStatus === 4) {
item.orderStatusDesc = '已收货';
} else {
item.orderStatusDesc = '已评价';
}
if(item.logisticsState === 110) {
item.logisticsStateDesc = '已接单';
} else if(item.logisticsState === 220) {
item.logisticsStateDesc = '运输中';
} else if(item.logisticsState === 140) {
item.logisticsStateDesc = '已揽收';
} else if(item.logisticsState === 260) {
item.logisticsStateDesc = '配送中';
} else {
item.logisticsStateDesc = '已签收';
}
});
console.log(orderList); // 我们同样得到了我们想要的结果,但原始数组已经被改变了
var orderList = Mock.mock({
'orderList|10-15': [
{
'contact|1': ['李白', '杜甫', '李商隐','陶渊明','李贺','孟浩然','苏轼','怀素','袁天罡','李淳风','秦始皇','李煜'],
'price|1-230.0-2': 1,
'orderStatus|1-5': 1,
'logisticsState|1': [110,220,140,260,250],
}
]
})

这段代码里的将状态码翻译成文字写的非常非常烂,之后我们会使用Map对象结合扩展运算符进行优化。

.indexOf和.findIndex

  • indexOf是ES5的API,findIndex是ES6的API

  • indexOffindIndex 都是从数组中找元素索引

  • indexOf 在数组中查找给定元素(值)的第一个索引,并返回,找不到返回 -1;findIndex 在数组中查找满足条件(函数)的第一个元素索引,并返回。否则返回 -1;

  • 实用程度:

  • 语法:

    • arr.indexOf(searchElement[, fromIndex])

      • searchElement 要查找的元素
      • fromIndex 可选 开始查找的位置。如果该索引值大于或等于数组长度,意味着不会在数组里查找,返回-1。如果参数中提供的索引值是一个负值,则将其作为数组末尾的一个抵消,即-3表示从倒数第三个元素开始查找(从左往右), 如果抵消后的索引值仍小于0,则整个数组都将会被查询。其默认值为0.
    • const index = arr.findIndex(callback(currentValue[, index[, array]])[, thisArg])

      • callback 用来测试数组的每个元素的函数
        • currentValue 当前元素
        • index 当前元素的索引
        • array 执行findIndex API的数组本身
1
2
3
4
5
['a','s','d','f','g','h'].indexOf('h',-2); // 5 从倒数第二个元素处往右开始查找
['a','s','d','f','g','h'].indexOf('f',-2); // -5 从倒数第二个元素处往右开始查找,找不到

const orderList = [{"contact":"李贺","price":4,"orderStatus":4,"logisticsState":260},{"contact":"袁天罡","price":23.7,"orderStatus":5,"logisticsState":220},{"contact":"袁天罡","price":219.5,"orderStatus":4,"logisticsState":220},{"contact":"苏轼","price":59,"orderStatus":4,"logisticsState":220},{"contact":"秦始皇","price":175.6,"orderStatus":2,"logisticsState":110},{"contact":"孟浩然","price":127.62,"orderStatus":3,"logisticsState":260},{"contact":"苏轼","price":108,"orderStatus":2,"logisticsState":250},{"contact":"李商隐","price":230.8,"orderStatus":4,"logisticsState":220},{"contact":"孟浩然","price":111.3,"orderStatus":4,"logisticsState":110},{"contact":"秦始皇","price":34.8,"orderStatus":3,"logisticsState":260}];
orderList.orderList.findIndex(item => item.orderStatus === 2); // 4

.lastIndexOf

  • 返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找(从右向左),从 fromIndex 处开始。
  • 语法:arr.lastIndexOf(searchElement[, fromIndex])
    • searchElement 要查找的元素
    • fromIndex 可选 从此位置开始逆向查找。默认为数组的长度减 1(arr.length - 1),即整个数组都被查找。如果该值大于或等于数组的长度,则整个数组会被查找。如果为负值,将其视为从数组末尾向前的偏移。即使该值为负,数组仍然会被从后向前查找。如果该值为负时,其绝对值大于数组长度,则方法返回 -1,即数组不会被查找。

lastIndexOfindexOfAPI是两个作用相同结果相反的API;相同点都是从数组中查找给定元素的索引,不同点是indexOf是从左往右查,lastIndexOf是从右往左查,indexOf 是查找元素在数组的第一个索引(同一元素,在数组中有多处,返回第一处索引),lastIndexOf 是查找元素在数组的最后一个索引(同一元素,在数组中有多处,返回最后一处索引)

代码和indexOf API相反,就不写了

.join

  • 这个API在js的第一个版本就有

  • join 根据指定分隔符(默认分隔符为英文逗号)将数组所有元素拼成字符串返回。如果数组只有一个项目,那么将返回该项目而不使用分隔符

  • 实用程度:

  • 语法:arr.join([separator])

    • separator 可选 指定一个字符串来分隔数组的每个元素,默认为英文逗号
1
2
3
4
['a','f','d','f','g','h'].join('<-->'); // "a<-->f<-->d<-->f<-->g<-->h"

const orderList = [{"contact":"李贺","price":4,"orderStatus":4,"logisticsState":260},{"contact":"袁天罡","price":23.7,"orderStatus":5,"logisticsState":220},{"contact":"袁天罡","price":219.5,"orderStatus":4,"logisticsState":220},{"contact":"苏轼","price":59,"orderStatus":4,"logisticsState":220},{"contact":"秦始皇","price":175.6,"orderStatus":2,"logisticsState":110},{"contact":"孟浩然","price":127.62,"orderStatus":3,"logisticsState":260},{"contact":"苏轼","price":108,"orderStatus":2,"logisticsState":250},{"contact":"李商隐","price":230.8,"orderStatus":4,"logisticsState":220},{"contact":"孟浩然","price":111.3,"orderStatus":4,"logisticsState":110},{"contact":"秦始皇","price":34.8,"orderStatus":3,"logisticsState":260}];
orderList.orderList.join('<----->'); // "[object Object]<----->[object Object]<----->[object Object]<----->[object Object]<----->[object Object]<----->[object Object]<----->[object Object]<----->[object Object]<----->[object Object]<----->[object Object]" 如果是array<Object> 转字符串不会把对象成字符串后再拼接

.reduce和.reduceRight

  • reducereduceRight 都是ES5就有的方法

  • 都是累加器;reduce 从左往右执行,reduceRight 从右往左执行

  • 适用场景 还记得讲模版字符串中可以使用变量的那个例子吗

  • 语法:

    • arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

    • arr.reduceRight(callback(accumulator, currentValue[, index[, array]])[, initialValue])

      • callback 一个回调函数,用来操作数组中的每个元素,可接受四个参数

        • accumulator 上一次调用回调的返回值,或提供的 initialValue。如果没有提供initialValue , 第一次函数执行时accumulator就是数组的第0个元素,currentValue是数组的第一个元素
        • currentValue 当前被处理的元素
        • index 可选 数组中当前被处理的元素的索引
        • array 可选 调用 reducet() 的数组
      • initialValue 可选 值用作回调的第一次调用的累加器。如果未提供初始值,则将使用并跳过数组中的最后一个元素。在没有初始值的空数组上调用reduce或reduceRight就会创建一个TypeError。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 模版字符串中使用变量的例子是这么写的
const prace = {title: '渡荆门送别', autor: '李白', content: ['渡远荆门外,来从楚国游。', '山随平野尽,江入大荒流。', '月下飞天镜,云生结海楼。', '仍怜故乡水,万里送行舟。']}

const render = function (accumulator, currentValue, index) {
return index === 1 ? '<p>' + accumulator + '</p>' + '<p>' + currentValue + '</p>' : accumulator + '<p>' + currentValue + '</p>';
}

const nodes = '<article><h3>' + prace.title + '</h3><address>' + prace.autor + '</address>' + prace.content.reduce(render) + '</article>';

// 可以看到上面例子由于我们没有提供 initialValue ,所以我们返回的时候做了判断
// 现在我们对上面例子做个简化和优化
['渡远荆门外,来从楚国游。', '山随平野尽,江入大荒流。', '月下飞天镜,云生结海楼。', '仍怜故乡水,万里送行舟。'].reduce((count,item) => {
return count + `<span>${item}</span>`
}, '')
// 输出 <span>渡远荆门外,来从楚国游。</span><span>山随平野尽,江入大荒流。</span><span>月下飞天镜,云生结海楼。</span><span>仍怜故乡水,万里送行舟。</span>
// 我们提供了初始累计是空字符串,然后就可以省略掉判断了

// 使用reduceRight
['渡远荆门外,来从楚国游。', '山随平野尽,江入大荒流。', '月下飞天镜,云生结海楼。', '仍怜故乡水,万里送行舟。'].reduceRight((count,item) => {
return count + `<span>${item}</span>`
},'')
// 输出 <span>仍怜故乡水,万里送行舟。</span><span>月下飞天镜,云生结海楼。</span><span>山随平野尽,江入大荒流。</span><span>渡远荆门外,来从楚国游。</span>

.shift和.pop

  • shiftpop 都是用来从数组中删除元素

  • shiftpop 都会改变原数组

  • shift删除数组的第一个元素,并返回该元素的值;pop删除数组的最后一个元素,并返回该元素的值

  • 语法

    • arr.shift()

    • arr.pop()

      • 当数组为空时返回undefined

这两个API很简单,也是较为常用的API,代码省略

.unshift和.push

  • unshiftpush都是用来向数组添加元素的
  • unshiftpush都会返回数组的新长度
  • unshiftpush都会改变原数组
  • unshift向数组的开头添加元素,push向数组的结尾添加元素
  • 语法
    • arr.unshift(element1, ..., elementN)
    • arr.push(element1, ..., elementN)
      • elementN 被添加到数组开头或结尾的元素
1
2
3
4
5
6
7
const list = [];
let length = list.unshift({name: '李白'}, str =>str, ['柴志阳']);
console.log(length,list) // 3 [{name: '李白'},str =>str, ['柴志阳']]

// push
length = list.push('a', 's', 909);
console.log(length,list) // 6 [{name: '李白'},str =>str, ['柴志阳'],'a', 's', 909]

这两个API也很简单,也很好理解,可以多用用,多感受下

.some和.every

  • someevery 都是ES5就有的API

  • someevery 都是用来测试数组元素是否可以通过测试条件(我们提供的一个测试函数),通过就返回 true ,否则返回 false ;不同的是数组中只要有一个元素通过测试some就会返回 true ,而every 需要所有元素都通过测试才会返回true

  • 语法

    • arr.some(callback(element[, index[, array]])[, thisArg])

    • arr.every(callback(element[, index[, array]])[, thisArg])

      • callback 用来测试每个元素的函数,它可以接收三个参数:

        • element 用于测试的当前值。
        • index 可选 用于测试的当前值的索引。
        • array 可选 当前数组。
      • thisArg 可选 执行 callback 时使用的 this 值。

      • 返回值 回调函数必须返回Boolean值

    注意: 如果使用箭头函数表达式来传入函数参数,thisArg 参数会被忽略,因为箭头函数在词法上绑定了 this 值。

1
2
3
const list = [{id: 1012098909, userName: '李白'}, {id: null, userName: '杜甫'}, {id: 102909890, userName: '松鼠航'}]
console.log(list.every(item => Boolean(item.id))); // false
console.log(list.some(item => Boolean(item.id))); // true

这两个判断很简单,就是一个并(&)一个或(|)。

.slice

  • 数组截取,根据传入的起始位置和截止位置从原数组中截取指定长度的元素组成新的数组返回,新数组为原数组的浅拷贝不会改变原数组;(官方描述:slice() 方法返回一个新的数组对象,这一对象是一个由 beginend 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。)

  • 语法:arr.slice([begin[, end]])

    • begin 可选 提取起始处的索引(从 0 开始),从该索引开始提取原数组元素。

      如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2) 表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。

      如果省略 begin,则 slice 从索引 0 开始。

      如果 begin 大于原数组的长度,则会返回空数组。

    • end 可选 提取终止处的索引(从 0 开始),在该索引处结束提取原数组元素。slice 会提取原数组中索引从 beginend 的所有元素(包含 begin,但不包含 end)。

      slice(1,4) 会提取原数组中从第二个元素开始一直到第四个元素的所有元素 (索引为 1, 2, 3的元素)。

      如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1) 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。

      如果 end 被省略,则 slice 会一直提取到原数组末尾。

      如果 end 大于数组的长度,slice 也会一直提取到原数组末尾。

    • 返回值 一个含有被提取元素的新数组。

slice 不会修改原数组,只会返回一个浅复制了原数组中的元素的一个新数组。原数组的元素会按照下述规则拷贝:

  • 如果该元素是个对象引用 (不是实际的对象),slice 会拷贝这个对象引用到新的数组里。两个对象引用都引用了同一个对象。如果被引用的对象发生改变,则新的和原来的数组中的这个元素也会发生改变。

  • 对于字符串、数字及布尔值来说(不是 StringNumber 或者 Boolean对象),slice 会拷贝这些值到新的数组里。在别的数组里修改这些字符串或数字或是布尔值,将不会影响另一个数组。

如果向两个数组任一中添加了新元素,则另一个不会受到影响。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const obj1 = {name: '李白', age: 18};
const list1 = [1,2,3,4,5];
const list = ['item1', 'item2', obj1, 'item3', list1, 'item4']; // 数组中obj1 和 list1 都是引用
console.log(list);

const copyList = list.slice(1); // 省略了结束位置,则从第二个元素开始截取
console.log(copyList);

list1.forEach(function(item,index) {
this[index] = item * 2;
}, list1); // 修改了list对list1的引用,修改list1,则copyList和list都会被改变
console.log(list,copyList);

list[2] = 'item5'; // 直接修改原始数组的元素,浅拷贝的数组也不会受影响
console.log(list,copyList);

.splice

  • splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容。此方法会改变原数组。

  • 可以删除元素,也可以替换元素,也可以插入元素

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

    • start 指定修改的开始位置(从0计数)。

      如果超出了数组的长度,则从数组末尾开始添加内容;

      如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n);

      如果负数的绝对值大于数组的长度,则表示开始位置为第0位。

    • deleteCount 可选 整数,表示要移除的数组元素的个数。

      如果 deleteCount 大于 start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。

      如果 deleteCount 被省略了,或者它的值大于等于array.length - start(也就是说,如果它大于或者等于start之后的所有元素的数量),那么start之后数组的所有元素都会被删除。

      如果 deleteCount 是 0 或者负数,则不移除元素。这种情况下,至少应添加一个新元素。

    • item1,item2,... 可选 要添加进数组的元素,从start 位置开始。如果不指定,则 splice() 将只删除数组元素。

    • 返回值 由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组。

1
2
3
4
5
6
7
8
9
10
11
const list = ['a', 1, ['李白'], {tip: '提示语'}];
// 在指定位置插入元素
const item = list.splice(2,0,'小白', '小二'); // 开始操作索引 2 ,删除元素0(也就是不删除元素),添加两个元素
console.log(item,list); // item 返回被删除元素组成的数组,没有元素被删除,所以 item 是空数组

// 替换元素
const updatedList = list.splice(2,2, {say: 'how are you'}, 'fine', ['how are you', 'fine'] ); // 开始操作索引2,删除两个元素,补充进3个元素
console.log(updatedList,list)

// 删除元素
console.log(list.splice(1,3), list); // 打印出来的第一个是被删除元素组成成的数组,第二个是被修改后的数组

其他(不常用)

from

  • 将一个可迭代对象创建为数组(官方描述:Array.from() 方法从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。)
  • 语法Array.from(arrayLike[, mapFn[, thisArg]])
    • arrayLike 想要转换成数组的可迭代对象
    • mapFn 可选 如果指定了该参数,新数组中的每个元素会执行该回调函数。(也就表示,先转成数组,然后在对数组进行map遍历)
    • thisArg 可选 可选参数,执行回调函数 mapFnthis 对象。
    • 返回值 新数组
1
2
3
4
5
6
7
8
// 字符串变数组
const iterableStr = '渡远荆门外,来从楚国游。';
const iterableStrList = Array.from(iterableStr, item =>`${item}${item}`); // ["渡渡", "远远", "荆荆", "门门", "外外", ",,", "来来", "从从", "楚楚", "国国", "游游", "。。"]

// Map变数组
// Map在之后的内容,不理解暂可忽略
const mapObj = new Map([['name', '李白'], ['age', 18]]);
const mapObjList = Array.from(mapObj); // [["name", "李白"], ["age", 18]]

js内置的可迭代对象有StringArrayTypedArrayMapSet

of

  • 此API是ES6新增的API
  • Array.of() 方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。(核心:用来创建数组
  • 语法:Array.of(element0[, element1[, ...[, elementN]]])
    • elementN 任意个参数,将按顺序成为返回数组中的元素。
    • 返回值为创建的数组
1
2
Array.of('周日', '周一', '周二', '周三', '周四'); // ['周日', '周一', '周二', '周三', '周四']
Array.of(6); // [6]

Array.of()Array 构造函数之间的区别在于处理整数参数:Array.of(7) 创建一个具有单个元素 7 的数组,数组长度为1,而 Array(7) 创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

.copyWithin

  • 此API为ES6新增API

  • 将数组的某些元素复制插入到数组的指定位置,并返回改变后的数组(官方描述:copyWithin() 方法浅复制数组的一部分到同一数组中的另一个位置,并返回它,不会改变原数组的长度。)

  • 特点:会修改原数组;

  • 语法:arr.copyWithin(target[, start[, end]])

    • target 【可选】 0 为基底的索引,复制序列到该位置。如果是负数,target 将从末尾开始计算。

      如果 target 大于等于 arr.length,将会不发生拷贝。如果 targetstart 之后,复制的序列将被修改以符合 arr.length

    • start 【可选】 0 为基底的索引,开始复制元素的起始位置。如果是负数,start 将从末尾开始计算。

      如果 start 被忽略,copyWithin 将会从0开始复制。

    • end 【可选】 0 为基底的索引,开始复制元素的结束位置。copyWithin 将会拷贝到该位置,但不包括 end 这个位置的元素。如果是负数, end 将从末尾开始计算。

      如果 end 被忽略,copyWithin 方法将会一直复制至数组结尾(默认为 arr.length)。

    • 返回值 为修改后的数组

1
2
3
const arr = ['a','s','d','f','g','h','1','2','3','4','5','6','j'];
const newArr = arr.copyWithin(2,5,8); // 复制3个元素 从索引5开始到8结束,不包含8; 从索引为2开始往右进行替换
console.log(arr,newarr); // 输出内容一样

copyWithin 会直接修改原数组,基于此,某些情况,其实我们没必要去接返回值,因为返回值也是被修改后的数组

.fill

  • 此API为ES6新增API
  • fill() 方法用一个固定值填充一个数组中从起始索引终止索引内的全部元素。不包括终止索引。
  • fill()copyWithin() 有相似性,都是替换数组元素。不同的是fill() 使用固定值替换,copyWithin()是从数组的指定起始位置和终止位置取元素来替换
  • 特点:1. 会修改原数组 2. 数组长度不变(隐含意思就是去填充替换空数组得到的还是空数组。指定的终止索引超过了数组本身的终止索引,也就到数组本身的终止索引就结束了,不会改变数组长度)
  • 语法:arr.fill(value[, start[, end]])
    • value 用来填充数组元素的固定值
    • start 【可选】起始索引,默认值为0。如果 start 是个负数, 则开始索引会被自动计算成为 arr.length + start
    • end 【可选】终止索引,默认值为 arr.length。如果 end 是个负数, 则结束索引会被自动计算成为 arr.length + end(长度是正数,end是负数,本质是减法,OK?)。
    • 返回值 为修改后的数组
1
2
3
const arr = ['a', 's', 'd', 'f'];
const newArr = arr.fill('s', 0, 3);
console.log(arr,newArr); // ["s", "s", "s", "f"]

如果你想要看start > end 是什么样子,请自行打印

.entries

  • 此API是ES6新增API
  • entries() 方法返回一个新的可迭代(Array Iterator)对象,该对象包含数组中每个索引的键/值对
  • 语法:arr.entries()
    • 返回值 一个新的 Array迭代器对象。Array Iterator是对象,它的原型(__proto__:Array Iterator)上有一个next()方法,可用用于遍历迭代器取得原数组的[key,value]
1
2
3
4
5
const arr = ['a', 6, {name: '张三'}, () => 18];
const iterator = arr.entries(); // 返回可迭代对象
console.log(iterator.next()); // { value: [0, "a"], done: false }; value是遍历当前成员的值 done表示遍历是否结束
const item1 = iterator.next().value;
console.log(item1); // [1, 6] 索引1 值是6

.keys

  • 此API是ES6新增API

  • keys() 方法返回一个包含数组中每个索引键的Array Iterator对象

  • 语法:arr.keys()

    • 一个新的 Array 迭代器对象。
1
2
3
4
const arr = ['a', 6, {name: '张三'}, () => 18];
const iterator = arr.keys();
console.log(iterator.next()); // { value: 0, done: false } value 是索引
console.log(iterator.next()); // { value: 0, done: false } value 是索引

.values

  • 此API是ES6新增API
  • values() 方法返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值
  • 语法:arr.values()
    • 一个新的 Array迭代对象。
1
2
3
4
const arr = ['a', 6, {name: '张三'}, () => 18];
const iterator = arr.values();
console.log(iterator.next()); // { value: "a", done: false } value 是元素
console.log(iterator.next()); // { value: 6, done: false } value 是元素

entries()keys()values() 都是返回一个新的可迭代对象。不同的是entries() 的可迭代对象中包含的是数组的每一个索引和索引对应的值;keys()的可迭代对象中包含的是数组的每一个索引;values()的可迭代对象中包含的是数组的每一个索引对应的值;

更简单说values()keys()合起来就是entries()

.flatMap

  • 暂时还是草案,未写入标准
  • flatMap()方法对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法
  • 语法:var new_array = arr.flatMap(callback(currentValue[, index[, array]])[, thisArg])
    • callback() 执行map()的函数,可以接收三个参数:
      • currentValue 当前正在数组中处理的元素
      • index 【可选】 数组中正在处理的当前元素的索引。
      • array 【可选】被调用的 map 数组
    • thisArg 【可选】执行 callback 函数时 使用的this
1
2
3
4
5
6
7
8
9
10
// 这段代码示例来自MDN
var arr1 = [1, 2, 3, 4];

console.log(arr1.map(x => [x * 2])); // [[2], [4], [6], [8]]

arr1.flatMap(x => [x * 2]); // [2, 4, 6, 8]

// only one level is flattened
arr1.flatMap(x => [[x * 2]]); // [[2], [4], [6], [8]]

注意:flatMap() 只能拉平一层

flatMap() 目前只是草案,在某些浏览器(IE,Edge)中并不支持

.reverse

  • reverse() 方法将数组中元素的位置颠倒,并返回该数组。该方法会改变原数组。

  • 语法:arr.reverse()

    • 返回值:颠倒后的数组。
1
2
3
const arr = [0,1,2,3,4,5,6,7,8,9];
const newArr = arr.reverse();
console.log(arr,newArr); // [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]