类方法
new
let arr = new Array(1, 2, 3);
1
错误示范
let arr = new Array([1, 2, 3]);
1
isArray
let a = [1, 2, 3];
console.log(Array.isArray(a));
1
2
from
Array.from()
- Array.from()将
伪数组对象
或iterator
转换成数组
伪数组对象:拥有一个length和若干个索引的对象
- 调用:Array.from(iterator[, mapFn, thisArg])
- 入参:Iterator[, 回调一次数组的map, map的绑定this]
- 返回:Array
- tip:回调mapFn只有两个参数 (item, index) => {}
- tip:使用thisArg时,mapFn就不能使用箭头函数
let arr = [1, 2, 3];
console.log(Array.from(arr));
let set = new Set(arr);
console.log(Array.from(arr));
let divs = document.querySelectorAll('div');
console.log(Array.from(divs));
Array.prototype.slice.call(divs);
1
2
3
4
5
6
7
8
9
10
11
12
13
相当于new Array().map(() => {})
let set = new Set([1, 2, 3]);
let arr = Array.from(set, (item, index) => `${index}:${item}`);
console.log(arr);
1
2
3
4
5
- 注:箭头函数没有this的值,所以要使用thisArg,回调函数就应该使用function
let set = new Set([180, 175, 170]);
let thisArr = ['张三', '李四', '王五'];
let arr = Array.from(set, function(item, index) {
return `${this[index]}: ${item}`;
}, thisArr);
console.log(arr);
1
2
3
4
5
6
7
8
of
Array.of()
与new Array()
/Array()
相似,都是创建新数组
console.log(Array.of(1, 2, 3));
console.log(new Array(1, 2, 3));
console.log(Array.of(3));
console.log(new Array(3));
1
2
3
4
5
6
增删改查
pop
- 作用:数组取出最后一项(改变原数组)
- 调用:arr.pop()
- 返回:删除的项
const arr = [1, 2, 3];
console.log(arr.pop());
console.log(arr);
1
2
3
push
- 作用:数组末尾添加项
- 调用:arr.push(item[, item...])
- 传入:any[, any]
- 返回:any
- tip:返回的是添加后数组的最后一项
const arr = [1, 2, 3, 4];
console.log(arr.push(5, 6, 7));
console.log(arr);
1
2
3
shift
- 作用:删除数组第一个元素
- 调用:arr.shift()
- 返回:any
const arr = [1, 2, 3, 4];
console.log(arr.shift());
console.log(arr);
console.log([].shift());
1
2
3
4
unshift
- 作用:向数组头添加项
- 调用:arr.unshift(item[, item...])
- 入参:any[, any...]
- 返回:Number(length)
- tip:插入的顺序就是入参顺序,返回的是插入后的长度
const arr = [1, 2, 3];
console.log(arr.unshift(5, 6));
console.log(arr);
1
2
3
期望:
const arr = [1, 2, 3];
console.log(arr.myUnshift(5, 6));
console.log(arr);
1
2
3
Array.prototype.myUnshift = function(...args) {
const arr = [...args, ...this];
for(let [index, value] of arr.entries()) {
this[index] = value;
}
return arr.length;
}
1
2
3
4
5
6
7
8
9
splice
- 作用:删除、插入数组(修改原数组)
- 调用:arr.splice(from[, delNum, newItem...])
- 入参:Number[, Number, any...]
- 返回:array
- tip:返回的是删除的数组
- tip:支持负值索引
const arr = [1, 10, 1000];
console.log(arr.splice(2, 0, 100));
console.log(arr);
console.log(arr.splice(1, 2));
console.log(arr);
1
2
3
4
5
6
7
8
9
const arr = [1, 2, 3];
console.log(arr.splice(-2, 1, 100));
console.log(arr);
1
2
3
4
slice
- 作用:切割数组,返回新的数组
- 调用:arr.slice(start, end)
- 入参:number, number
- 返回:Array(新数组,不改变原数组)
const arr = [1, 2, 3];
console.log(arr.slice());
console.log(arr.slice(1));
console.log(arr.slice(1, -1));
console.log(arr);
1
2
3
4
5
6
includes
- 作用:检查数组中是否包含指定的项,可以指定开始查找的位置
- 调用:arr.includes(item[, start])
- 入参:any[, Number]
- 返回:boolean
const arr = [1, 2, 3, 4];
console.log(arr.includes(2));
console.log(arr.includes(2, 2));
1
2
3
const arr = [1, 1, 1, 1];
console.log(arr.includes(1, 4));
1
2
every
- 作用:查看数组是否所有项都满足条件
- 调用:arr.every((item, index, arr) => boolean, thisArg)
- 入参:Function[, Object]
- 返回:Boolean
- tip:要使用this就不能使用箭头函数
const arr = [4, 4, 5, 6];
console.log(arr.every((item, index, arr) => {
return item < 10;
}))
1
2
3
4
const arr = [14, 15, 16, 19];
const obj = {
name: 'hdy',
age: 18
}
console.log(arr.every(function(item, index, arr){
return item < this.age
}, obj))
1
2
3
4
5
6
7
8
some
- 作用:判断数组中是否有符合要求的项
- 调用:arr.some((item, index, arr) => bool, thisArg)
- 入参:Function[, obj]
- 返回:Boolean
const arr = [1, 10, 100, 1000];
console.log(arr.some(item => item > 1000));
console.log(arr.some(item => item > 100));
1
2
3
4
const me = {
name: 'coderhdy',
age: 18
}
const others = [
{
name: '小黄',
age:15
},
{
name: '小张',
age:16
},
{
name: '小李',
age:13
},
]
console.log(others.some(function(item) {item.age > this.age}, me));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
find
- 作用:找到数组中第一个满足条件的项
- 调用:arr.find((item, index, arr) => bool, thisArg)
- 入参:Function[, Object]
- 返回:any(数组中满足条件的项)
- tip:使用thisArg就不能使用箭头函数
const arr = [1, 10, 100, 'coderHdy'];
console.log(arr.find(item => typeof item !== 'number'));
1
2
3
const arr = [
{
name: '张三',
age: 18
},
{
name: '李四',
age: 19
},
{
name: '小尤',
age: 32
}
];
const obj = {
name: 'coderHdy',
age: 21
}
console.log(arr.find(function(item) {
return item.age > this.age;
}, obj)
.name);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
findIndex
- 作用:找到符合条件的第一项的下标
- 调用:arr.findIndex((item, index, arr) => bool, thisArg)
- 入参:Function[, Object]
- 返回:Number
- tip:使用thisArg就不能使用箭头函数
const arr = [1, 2, 3, 'coderHdy'];
console.log(arr.findIndex(item => typeof item !== 'number'));
1
2
3
const arr = [
{
name: '张三',
age: 18
},
{
name: '李四',
age: 19
},
{
name: '小尤',
age: 32
}
];
const obj = {
name: 'coderHdy',
age: 21
}
console.log(arr.findIndex(function(item) {
return item.age > this.age;
}, obj));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
indexOf
- 作用:找到指定元素的下标,不存在则返回 -1
- 调用:arr.indexOf(item[, start])
- 入参:any[, Number]
- 返回:Number
const arr = ['小黄', '小张', '小李' , '小秋', '小张'];
console.log(arr.indexOf('小张'));
console.log(arr.indexOf('小张', 2));
1
2
3
期望:
const arr = ['小张', '小黄', '小李', '小黄'];
console.log(findAllIndex(arr, '小黄'));
1
2
function findAllIndex(arr, str) {
const ans = [];
let cIndex = arr.indexOf(str);
while (cIndex > -1) {
ans.push(cIndex);
cIndex = arr.indexOf(str, cIndex + 1);
}
return ans;
}
1
2
3
4
5
6
7
8
9
lastIndexOf
- 作用:反向查找指定元素的下标,可以指定末尾开始的下标
- 调用:arr.lastIndexOf(item[, from])
- 入参:any[, Number]
- 返回:Number
- tip:from支持负值,可以从后数
const arr = ['小张', '小张', '小李', '小张'];
console.log(arr.lastIndexOf('小张'));
console.log(arr.lastIndexOf('小张', 2));
console.log(arr.lastIndexOf('小张', 0));
console.log(arr.lastIndexOf('小张', -2));
1
2
3
4
5
6
7
at
支持的环境
环境 | 版本 |
chrom | 92 |
firefox | 90 |
node | 16.6 |
const arr = [1, 2, 3];
console.log(arr.at(-1));
1
2
3
也可以直接判断index将其转换为正的
function at(arr, index) {
return index < 0 ? (index === -1 ? arr.slice(index) : arr.slice(index, index + 1))[0] : arr[index];
}
const arr = [1, 2, 3];
console.log(at(arr, 2));
console.log(at(arr, -1));
console.log(at(arr, -2));
1
2
3
4
5
6
7
8
9
10
操作数组
concat
- 作用:拼接数组,自动打平一层入参,不改变原数组
- 调用:arr1.concat(arr2[, arr3...])
- 入参:any[, any...]
- 返回:Array
- tip:如果入参是数组,自动打平一层(flat)
const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
console.log(arr.concat(arr2, arr));
console.log([...arr2, ...arr]);
1
2
3
4
5
6
7
8
9
10
11
const arr = [1, 2, 3];
console.log(arr.concat(4));
console.log(arr.concat([5, 6, 7, [8]]));
1
2
3
4
function concat(arr, ...args) {
let newArr = [...arr];
args.forEach(item =>
Array.isArray(item) ? newArr.push(...item) : newArr.push(item)
);
return newArr;
}
const arr = [1, 2, 3];
const arr2 = [4, 5, 6];
console.log(concat(arr, arr2));
console.log(concat(arr, 6, 6, 6, arr2));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function concat(...arrs) {
return arrs.flat();
}
1
2
3
copyWithin
- 作用:将原数组的目标index变为指定index区间的数,不会改变原数组长度
- 调用:arr.copyWithin(index, start, end);
- 入参:Number, Number, Number
- 返回:改变后的原数组
- tip:替换的长度根据(end - start)决定
const arr = [1, 2, 3, 4, 5];
const arr2 = [1, 2, 3, 4, 5];
console.log(arr.copyWithin(1, 3, 5))
console.log(arr2.copyWithin(2, 1, 3))
1
2
3
4
5
fill
- 作用:将数组填充,改变原数组
- 调用:arr.fill(item[, start, end])
- 入参:any(填充值)[, Number, Number]
- 返回:Array
const arr = [1, 2, 3, 4, 5];
console.log(arr.fill(6, 2, 4));
console.log(arr.fill(6));
console.log(arr);
1
2
3
4
5
join
- 作用:将数组加入指定的分隔符转化成字符串
- 调用:arr.join(str)
- 入参:String
- 返回:String
- tip:入参不传默认是逗号
const arr = [1, '本书', true];
console.log(arr.join());
console.log(arr.join(''));
1
2
3
const str = '1,本书,true';
console.log(str.split(','));
1
2
reverse
- 作用:反转数组,改变原数组
- 调用:arr.reverse()
- 返回:原数组引用
const arr = [1, 2, 3, 4, 5];
console.log(arr.reverse());
console.log(arr);
1
2
3
sort
- 作用:排列数组,改变原数组
- 调用:arr.sort((a, b) => Number)
- 入参:conpareFn
- 返回:原数组引用
conpareFn
- 形式:(a, b) => Number
- 返回值 > 0:a在后面
- 返回值 < 0:a在前面
const arr = [1000, 10, 100, 1];
console.log(arr.sort((a, b) => {
if (a > b) {
return 1;
} else {
return -1;
}
}));
console.log(arr);
console.log(arr.sort((a, b) => a - b));
1
2
3
4
5
6
7
8
9
10
11
12
13
console.log('a' > 'b');
console.log('ba' > 'bb');
1
2
期望:
const names = ['Delta', 'alpha', 'CHARLIE', 'bravo'];
console.log(sortIt(names));
1
2
function sortIt(names) {
const lower = names.map((item, index) => ({idx: index, name: item.toLowerCase()}));
lower.sort((a, b) => {
return +(a.name > b.name) || +(a.name === b.name) - 1;
});
const ans = lower.map(({ idx }) => names[idx]);
return ans;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
flat
- 作用:打平多维数组,不改变原数组
- 调用:arr.flat(deepth)
- 入参:Number(可选,默认是1)
- 返回:Array
- tip:可入参infinity直接无限打平成一维数组
const arr = [1, 2, [10, 20, [100, 200]]];
console.log(arr.flat());
console.log(arr);
console.log(arr.flat(2));
1
2
3
4
5
const arr = [1, 2, [10, 20, [100, 200, [1000, 2000]]]];
console.log(arr.flat(Infinity));
1
2
3
function flat(arr, deepth = 1) {
return arr.reduce((pre, item) =>
pre.concat(Array.isArray(item) && deepth > 1 ? flat(item, deepth - 1) : item)
, []);
}
const arr = [1, 2, [10, 20, [100, 200, [1000, 2000]]]];
console.log(flat(arr));
console.log(arr);
console.log(flat(arr, 2));
1
2
3
4
5
6
7
8
9
10
11
12
13
function deepFlat(arr) {
return arr.reduce((pre, item) =>
pre.concat(Array.isArray(item) ? deepFlat(item) : item)
, [])
}
const arr = [1, 2, [10, 20, [100, 200, [1000, 2000]]]];
console.log(deepFlat(arr));
1
2
3
4
5
6
7
8
9
10
toString
- 作用:将数组转化成字符串,以逗号分隔,不改变原数组
- 调用:arr.toString()
- 返回:String
const arr = [1, 2, true, '黄']
console.log(arr.toString());
console.log(arr);
1
2
3
高级方法
filter
- 作用:指定条件筛选数组项,返回新数组,不改变原数组
- 调用:arr.filter((item, index, arr) => bool, thisArg)
- 入参:Function[, Object]
- 返回:Array
- tip:使用thisArg不能使用箭头函数
const arr = [1, 10, 100, 1000];
console.log(arr.filter(item => item > 50));
console.log(arr);
1
2
3
4
const arr = [1, 10, 100 , 1000];
const obj = {
name: 'hdy',
age: 18
};
console.log(arr.filter(function(item) {
return item > this.age;
}, obj));
1
2
3
4
5
6
7
8
9
function filter(arr, fn, thisArg) {
return arr.reduce((pre, item, index, a) => {
return fn.call(thisArg, item, index, a) ? [...pre, item] : pre;
}, [])
}
const arr = [1, 10, 100];
const arr2 = filter(arr, function(item, index, arr){
return item > 9;
});
console.log(arr2);
1
2
3
4
5
6
7
8
9
10
11
function filter(arr, fn, thisArg) {
let ans = [];
for (let [index, item] of Object.entries(arr)) {
if (fn.call(thisArg, item, index, arr)) {
ans.push(item);
}
}
return ans;
}
const arr = [1, 10, 100];
const arr2 = filter(arr, function(item, index, arr){
return item > 9;
});
console.log(arr2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
forEach
- 作用:以迭代器的形式遍历数组
- 调用:arr.forEach((item, index, arr) => {}, thisArg)
- 入参:function[, obj]
- 返回:undefined
- tip:forEach无法中断,且遍历项不会中途改变遍历的项
const arr = ['name', 'age', 'book', 'work'];
const obj = {
name: 'hdy',
age: 18,
book: '红宝书',
work: '前端工程师'
}
arr.forEach(function(item) {
console.log(this[item])
}, obj);
1
2
3
4
5
6
7
8
9
10
11
12
const arr = [1, 10, 100, 1000];
arr.forEach(item => {
console.log(item);
if (item > 99) return;
});
1
2
3
4
5
6
const arr = [1, 10, 100, 1000];
arr.some(item => {
console.log(item);
return item > 9;
});
1
2
3
4
5
6
const arr = [1, 10, 100, 1000];
arr.forEach((item, index, arr) => {
console.log(item);
if (item > 9) {
arr.splice(index, 0, 99);
}
})
console.log(arr);
1
2
3
4
5
6
7
8
map
- 作用:将数组执行一个处理函数,返回新的数组
- 调用:arr.map((item, index, arr) => newItem, thisArg)
- 入参:function[, obj]
- 返回:Array
const arr1 = [1, 2, 3, 4];
const arr2 = arr1.map((item, index) => item * index);
console.log(arr1);
console.log(arr2);
1
2
3
4
5
const obj = {
name: 'hdy'
}
const arr1 = [18, 19, 20];
const arr2 = arr1.map(function (item) {
const obj = JSON.parse(JSON.stringify(this));
obj.age = item;
return obj;
}, obj);
console.log(arr2);
1
2
3
4
5
6
7
8
9
10
11
const map = Array.prototype.map;
const str = '我是coderHdy';
const arr = map.call(str, item => item.charCodeAt(0));
console.log(arr);
1
2
3
4
5
const arr = ['1', '2', '2', '2'];
console.log(arr.map(parseInt));
1
2
parseInt其实接收两个参数:parseInt(str, type);
来决定是几进制
而map给回调函数传三个参数,第二个是index,index变成了进制,所以导致转换错误
二进制里面2就是非法的。
reduce
reduce
- 作用:遍历数组,获得一个迭代出来的结果
- 调用:arr.reduce((pre, item, index, arr) => {}, pre)
- 入参:function, any
- 返回:any
let arr = [1, 10, 100, 1000];
const sum = arr.reduce((pre, item, index, arr) => {
return item + pre;
}, 0)
console.log(sum);
1
2
3
4
5
6
期望:
const obj = {
name: '张三',
age: 18,
books: [
'蝴蝶书',
'红宝书'
]
}
const str = "我是${name},我今年${age},我喜欢读${books[1]}。";
console.log(template(obj, str));
1
2
3
4
5
6
7
8
9
10
11
function template(obj, str) {
const reg1 = /\$\{(.+?)\}/g;
const reg2 = /\[(.+?)\]/g;
return str.replace(reg1, (_, match) => {
let attrs = match.replace(reg2, (_, match2) => {
return "." + match2;
})
return attrs.split('.').reduce((pre, item) => pre[item], obj);
})
}
1
2
3
4
5
6
7
8
9
10
11
12
期望:
let arr1 = [[0, 1], [2, [3]], [4, 5]]
console.log(deepFlat(arr1));
1
2
function deepFlat(arr) {
return arr.reduce((pre, item) => pre.concat(Array.isArray(item) ? deepFlat(item) : item), [])
}
1
2
3
期望:
const names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
console.log(getShowTimes(names));
1
2
function getShowTimes(arr) {
return arr.reduce((pre, item) => {
if (pre[item]) {
pre[item]++;
} else {
pre[item] = 1;
}
return pre;
}, {})
}
1
2
3
4
5
6
7
8
9
10
期望:
const arr = [
{
name: '小黄',
age: 18
},
{
name: '小张',
age: 15
},
{
name: '小李',
age: 18
},
{
name: '小秋',
age: 15
},
{
name: '小冬',
age: 16
},
]
console.log(classify(arr));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function classify(arr) {
return arr.reduce((pre, item) => {
if (pre[item.age]) {
pre[item.age].push(item.name);
} else {
pre[item.age] = [item.name];
}
return pre;
}, {});
}
1
2
3
4
5
6
7
8
9
10
期望:
let arr = [1, 2, 3, 1, 4, 1];
console.log(noRepeat(arr));
1
2
function noRepeat(arr) {
return arr.reduce((pre, item, index) => {
if (!pre.includes(item)) {
pre.push(item);
}
return pre;
}, [])
}
1
2
3
4
5
6
7
8
function noRepeat(arr) {
return Array.from(new Set(arr));
}
1
2
3
期望:
const fn1 = (i) => new Promise((resolve) => setTimeout(() => resolve(i + 1), 1000));
const fn2 = (i) => new Promise((resolve) => setTimeout(() => resolve(i + 1), 1000));
const fn3 = (i) => new Promise((resolve) => setTimeout(() => resolve(i + 1), 2000));
const fn4 = (i) => new Promise((resolve) => setTimeout(() => resolve(i + 1), 1000));
goPromise([fn1, fn2, fn3, fn4]);
1
2
3
4
5
6
7
function goPromise(arr) {
arr.reduce((pre, item) => pre.then(item), Promise.resolve(11))
}
1
2
3
期望
const chain = new Chain();
chain.log(1)
.wait(2000)
.log(2)
.wait(3000)
.log(3)
console.log('同步代码');
1
2
3
4
5
6
7
8
class Chain {
log(i) {
console.log(i);
return this;
}
wait(time) {
let end = +new Date() + time;
while (+new Date() < end) {}
return this;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
class Chain {
fns = [];
constructor() {
setTimeout(() => {
this.fns.reduce((pre, item) => pre.then(item), Promise.resolve());
});
}
log(i) {
const fn = () => new Promise(resolve => {
console.log(i);
resolve();
});
this.fns.push(fn);
return this;
}
wait(time) {
const fn = () => new Promise(resolve => setTimeout(() => resolve(), time));
this.fns.push(fn);
return this;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
原BUG:事件轮询只能查一轮
const chain = new Chain();
chain.log(1)
.wait(2)
.log(2)
.wait(3)
.log(3)
setTimeout(() => chain.wait(3).log(3), 1000);
console.log('同步代码');
1
2
3
4
5
6
7
8
9
10
11
class Chain {
cThen = Promise.resolve();
log(i) {
const fn = () => new Promise(resolve => {
console.log(i);
resolve();
});
this.cThen = this.cThen.then(fn);
return this;
}
wait(time) {
const fn = () => new Promise(resolve => setTimeout(() => resolve(), time * 1000));
this.cThen = this.cThen.then(fn);
return this;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
reduceRight
- 作用:从右往左迭代数组,得出迭代结果
- 调用:arr.reduceRight((pre, item, index, arr) => pre, pre)
- 入参:Function, any
- 返回:any
const arr = [1, 2, 3, 4];
console.log(arr.reduce((pre, item, index, arr) => pre + item, ''));
console.log(arr.reduceRight((pre, item, index, arr) => pre + item, ''));
1
2
3
4
迭代器
keys
- 作用:拿到所有项的键值(迭代器的形式)
- 调用:arr.keys()
- 返回:Iterator
- tip:和Object.keys(arr) 有区别
const arr = [1, 2, ,4];
console.log(arr.keys().next().value);
console.log([...arr.keys()]);
console.log(Object.keys(arr));
1
2
3
4
5
6
entries
- 作用:将数组以
迭代器
的形式返回 - 调用:arr.entries()
- 返回:数组的迭代器
const arr = [1, 2, 3, 4];
let arrEts = arr.entries();
console.log(arrEts.next());
1
2
3
4
const arr = [1, 2, 3, 4];
let arrEts = arr.entries();
for( let [index, value] of arrEts) {
console.log(value);
}
1
2
3
4
5
6
values
- 作用:拿到所有的值,以迭代器方式返回
- 调用:arr.values()
- 返回:Iterator
const arr = [1, 10, 100, 1000];
console.log(arr.values().next().value);
1
2
Symbol.iterator
- 作用:将数组返回成一个迭代器
- 调用:arr[ Symbol.iterator ] ()
- 返回:Iterator
- tip:默认情况下,实际效果和values() 一样
const arr = [1, 10, 100];
const arrItt = arr[Symbol.iterator]();
const values = arr.values();
console.log(arrItt.next().value);
console.log(values.next().value);
1
2
3
4
5
6