Array数组基础知识

264 阅读11分钟

一、创建数组的方法

1. 使用Array构造函数

let arr = new Array()

如果给构造函数传入一个数值 那么这个数值会被作为数组的length值

let arr = new Array(2)
console.log(arr) // [undefined,undefined]

arr数组中有两个元素,两个元素的值都为undefined

Array构造函数传入要保存的元素

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

创建数组时 也可省略new关键字

var arr3 = Array(2) // length为2的数组 省略new也是可以的
console.log(arr3);

2.使用数组字面量表示法

let arr = [] // 空数组

也可以给数组中传入要保存的元素

let colors = ['red', 'green', 'blue'];
console.log(colors); // ['red', 'green', 'blue']

3.ES6新增两个创建数组的静态方法

3.1 from() 类数组结构转换为数组实例

3.1.1语法

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

3.1.2参数

arrayLike:想要转换成数组的伪数组对象或可迭代对象

mapFn(可选):新数组中的每个元素会执行该回调函数

thisArg(可选):改变函数的this指向

3.1.3返回值

新的数组

3.1.4示例:

1.字符串生成数组

console.log(Array.from('wang')); // ['w', 'a', 'n', 'g']

2.集合和映射生成数组

const m = new Map().set(1, 2).set(3, 4);
const s = new Set().add(1).add(2).add(3).add(4)
console.log(Array.from(m)); // [[1,2],[3,4]]
console.log(Array.from(s)); //  [1, 2, 3, 4]

3.类数组对象生成数组

function getArgsArray() {
	return Array.from(arguments)
}
console.log(getArgsArray('red', 'yellow', 'green')); //  ['red', 'yellow', 'green']

4.其他可迭代对象

const iter = {
	*[Symbol.iterator]() {
		yield 1;
		yield 2;
		yield 3;
		yield 4;
	}
}
console.log(Array.from(iter)); // [1, 2, 3, 4]

5.带有必要属性的自定义对象

const arrayLikeObject = {
	0: 1,
	1: 2,
	2: 3,
	3: 4,
	length: 4
}
console.log(Array.from(arrayLikeObject)); // [1, 2, 3, 4]

6.在Array.from()方法中使用剪头函数

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

7.改变函数的this指向

console.log(Array.from(
	a1,
	function (x) {
		return x ** this.exponent
	},
	{ exponent: 3 }
));
//  [1, 8, 27, 64]

3.2 of() 一组参数转换为数组实例

console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4]
console.log(Array.of('football', 'basketball')); // ['football', 'basketball']
3.2.1语法

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

3.2.2参数

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

3.3.3返回值

新的数组

3.3.4示例:

1.与构造函数创建数组不同 如果参数为一个数字的话 则这个数字会作为数组的数据之一

Array.of(1); // [1]

2.兼容旧环境

Array.prototype.slice.call('1234');

二、数组空位(避免使用如果实在需要用undefined代替)

1.概念

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

2.示例

举个🌰:

const options = [, , , ,];
console.log(options.length); // 4
console.log(options); // [,,,,]

ES6新增普遍将这些空位当成存在的元素,只不过值为undefined

const options = [1, , , 5];
for (const option of options1) {
	console.log(option === undefined);
}
// false
// true
// true
// false

通过这个🌰我们可以发现 ES6默认把这些空位的值当成undefined

const a = Array.from([,,,]);
for (const val of a) {
  alert(val === undefined);
}
// true
// true
// true
const b = Array.from([1,,,,5]);
for (const val of b) {
	alert(val);
}
// 1
// undefined
// undefined
// undefined
// 5

ES6之前的方法则会忽略这个空位 具体方法具体表现

const options = [1,,,,5];
// map会跳过空位置
console.log(options.map(()=>6))
// [6,undefined,undefined,undefined,6]
// join()视空位置为空字符串
console.log(options.join('-'));
// '1----5'

三、数组索引

1.概念

length是Array的实例属性。返回或设置一个数组中的元素个数

范围:

0 到 2^32-1 的整数

2.示例

var numbers = [1, 2, 3, 4]
console.log(numbers.length); // 4

利用length属性可以做很多的事情 比如添加/删除/替换数组 遍历数组等等

1.添加数组元素

var numbers = [1, 2, 3, 4];
numbers[numbers.length] = 5;
// 添加到最后位置元素5
console.log(numbers) // [1,2,3,4,5]

2.删除数组元素

var numbers = [1, 2, 3, 4];
numbers.length = 3;
console.log(numbers); // [1,2,3]

3.遍历数组

var numbers = [1, 2, 3, 4];
for (let i = 0;i<numbers.length;i++){
	console.log(numbers[i]);
}
// 1
// 2
// 3
// 4

5.替换数组元素

var numbers = [1, 2, 3, 4];
// 替换索引为2的元素为hello
numbers[2] = 'hello'
console.log(numbers); // [1,2,'hello',4]

四、检测数组

判断一个对象是不是数组

1.instanceof操作符

var numbers = [1, 2, 3, 4];
console.log(numbers instanceof Array)
// true

2.Array.isArray()方法

var numbers = [1, 2, 3, 4];
console.log(Array.isArray(numbers));
// true

五、Array常用的方法

1.迭代器方法(检索数组内容)

Array原型上暴露了3个用于检索数组内容的方法

1.keys()返回数组索引的迭代器

1.1语法

arr.keys()

1.2返回值

一个新的Array迭代器对象

1.3示例
const a = ["foo", "bar", "baz", "qux"];
const aKeys = Array.from(a.keys()) //  keys()数组索引的迭代器
console.log(aKeys); // [0, 1, 2, 3]

2.values()返回数组元素的迭代器

2.1语法

arr.values()

2.2返回值

一个新的Array迭代器对象

2.3示例
const a = ["foo", "bar", "baz", "qux"];
const aValues = Array.from(a.values());
// values()数组元素的迭代器
console.log(aValues); 
// ['foo', 'bar', 'baz', 'qux']

使用for...of循环进行迭代

for (let item of aValues) {
	console.log(item);
}
// foo
// bar
// baz
// qux

3.entries()返回索引/值对的迭代器

3.1语法

arr.entries()

3.2返回值

一个新的Array迭代器对象

3.3示例
const a = ["foo", "bar", "baz", "qux"];
const aEntries = Array.from(a.entries());
// entries()索引/值对的迭代器
console.log(aEntries); 
// [[0,'foo'],[1,'bar'],[2,'baz'],['3,qux']]

使用ES6解构在循环中拆分键/值对

for (const [index, element] of a.entries()) {
	console.log(index);
  console.log(element);
}
// 0
// foo
// 1
// bar
// 2
// baz
// 3
// qux

2.复制和填充方法

2.1 copyWithin() 批量复制方法

2.1.1 语法

arr.copyWithin(target[, start[, end]])

2.1.2 参数

target:复制索引0开始的内容插入到索引target开始的位置

start:开始复制元素的起始位置 默认从0开始复制

end:开始复制元素的结束位置 但不包括end这个索引的元素

注意:如果值大/小于索引值 则会忽略

2.1.3 返回值

改变后的数组

2.1.4 示例
let ints, reset = ()=>{
	ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}
reset();
ints.copyWithin(5); // 复制索引0开始的内容插入到索引5开始的位置 
// [0, 1, 2, 3, 4, 0, 1, 2, 3, 4]

reset();
ints.copyWithin(0, 5) // 复制索引5开始的内容插入到索引0开始的位置
console.log(ints); // [5, 6, 7, 8, 9, 5, 6, 7, 8, 9]

reset()
ints.copyWithin(4, 0, 3) // 复制索引0-3的内容插入到索引4开始的位置
console.log(ints); // [0, 1, 2, 3, 0, 1, 2, 7, 8, 9]

reset()
ints.copyWithin(4, -4, -1) // 复制索引0-3的内容插入到索引4开始的位置
console.log(ints); // [0, 1, 2, 3, 6, 7, 8, 7, 8, 9]

2.2 fill() 填充数组方法

2.2.1 语法

arr.fill(value[, start[, end]])

2.2.2 参数

value:用来填充数组元素的值

start:起始索引,默认值为0

end:终止索引,默认值为 this.length

注意:start 是个负数, 则开始索引会被自动计算成为 length+start

2.2.3 返回值

修改后的数组

2.2.4 示例
const zeroes = [0, 0, 0, 0, 0]
zeroes.fill(5) // 用5填充整个数组
console.log(zeroes); // [5, 5, 5, 5, 5]

zeroes.fill(0) // 重置
zeroes.fill(6, 3) // 用6填充索引大于等于3的方法
console.log(zeroes); // [0, 0, 0, 6, 6]

zeroes.fill(0) // 重置
zeroes.fill(7, 1, 3) // 用7填充大于等于1小于3的方法
console.log(zeroes); // [0, 7, 7, 0, 0]

zeroes.fill(0) // 重置
// -4 + zeroes.length = 1
// -1 + zeroes.length = 4
zeroes.fill(8, -4, -1) // 用7填充大于等于1小于4的方法
console.log(zeroes); // [0, 8, 8, 8, 0]

zeroes.fill(0) // 重置
zeroes.fill(1, -10, -6) // 超出范围 忽略
console.log(zeroes); // [0, 0, 0, 0, 0]
zeroes.fill(1, 10, 16) // 超出范围 忽略
console.log(zeroes); // [0, 0, 0, 0, 0]
zeroes.fill(2, 4, 2) // 索引反向 忽略
console.log(zeroes); // [0, 0, 0, 0, 0]
zeroes.fill(2, 2, 10) // 部分可用填充部分
console.log(zeroes); // [0, 0, 2, 2, 2]

3.转换方法

3.1 toLocaleString()返回一个字符串表示数组中的元素

3.1.1 语法

arr.toLocaleString([locales[,options]]);

3.1.2 参数

locales(可选)

options(可选)

3.1.3 返回值

表示数组元素的字符串

3.1.4 示例
let colors = ['red', 'blue', 'green'];
console.log(colors.toLocaleString()); // red,blue,green

3.2 toString()返回一个字符串,表示指定的数组及其元素

3.2.1 语法

arr.toString();

3.1.2 返回值

一个表示指定的数组及其元素的字符串

3.1.3 示例
let colors = ['red', 'blue', 'green'];
console.log(colors.toString()); // red,blue,green
3.1.4 toString()和toLocaleString()的区别
let person1 = {
	toLocaleString() {
		return 'cc'
	},
  toString() {
    return 'gg'
  },
};
let person2 = {
	toLocaleString() {
     return 'yy'
  },
  toString() {
     return 'ww'
  },
}
let people = [person1, person2]
alert(people); // gg ww alert调用的是toString()方法
console.log(people.toString()); // gg,ww
console.log(people.toLocaleString()); // cc,yy

3.3 valueOf() 返回的是数组本身

3.3.1示例
let colors = ['red', 'blue', 'green'];
console.log(colors.valueOf()); // ['red', 'blue', 'green']

3.4 join() 将一个数组/类数组的所有元素连接成一个字符串并返回这个字符串

3.4.1 语法

arr.join([separator])

3.4.2 参数

separator(可选):分隔符 默认为,相连数组元素

3.4.3 返回值

字符串 如果数组索引为0 则返回空字符串

3.4.4 示例
let colors = ['red', 'blue', 'green'];
console.log(colors.join()); // red, blue, green

使用分隔符 || 分隔数组元素

console.log(colors.join('||')); // red||blue||green

如果数组元素中有null/undefined元素的话 join返回的结果为空字符串

let hobbies = ['football', undefined, 'basketball']
console.log(hobbies.join('|')); // football||basketball

注意:toString()|toLocaleString()|valueOf()返回的结果与join()相同

4.栈方法

数组对象可以像栈一样 也就是一种限制插入和删除项的数据结构 后进先出

4.1 push() 将一个或多个元素添加到数组的末尾

4.1.1 语法

arr.push(element1, ..., elementN)

4.1.2 参数

elementN:被添加到数组末尾的元素

4.1.3 返回值

调用该方法 返回一个新的length

4.1.4 示例
let colors = ['red', 'blue', 'green'];
colors.push('white', 'black');
console.log(colors); 
// ['red', 'blue', 'green', 'white','black']

4.2 pop() 删除最后一项数组元素

4.2.1 语法

arr.pop()

4.2.2 返回值

从数组中删除的元素; 如果数组为空则返回undefined

4.2.3 示例
colors.pop()
console.log(colors); //  ['red', 'blue', 'green', 'white']
console.log(colors.length); // 4

5.队列方法

队列以先进先出形式限制访问

5.1 shift() 删除第一项数组元素

4.2.1 语法

arr.shift()

4.2.2 返回值

从数组中删除的元素; 如果数组为空则返回undefined

4.2.3 示例
let colors = ['red', 'blue', 'green'];
console.log(colors.shift()); // ['blue','green']

5.2 unshift() 将一个或多个元素添加到数组的开头

5.2.1 语法

arr.unshift(element1, ..., elementN)

5.2.2 参数

elementN:被添加到数组开头的元素

5.2.3 返回值

调用该方法 返回一个新的length

4.1.4 示例
let colors = ['red', 'blue', 'green'];
colors.unshift('skyblue', 'orange');
console.log(colors); // ['skyblue','orange','red','blue','green']

6.排序方法

6.1 reverse() 翻转数组

6.1.1 语法

arr.reverse()

6.1.2 返回值

颠倒后的数组

6.1.3 示例
let numbers = [1, 3, 4, 5, 2]
console.log(numbers.reverse()); // [2, 5, 4, 3, 1]

6.2 sort() 升序排序

6.2.1 语法

arr.sort([compareFunction])

6.2.2 参数

compareFunction(可选):用来指定按某种顺序进行排列的函数

firstE1:第一个用于比较的元素

secondE1:第二个用于比较的元素

6.2.3 返回值

排序后的数组

6.2.4 示例

sort()会按照数值的字符串形式重新排序

let values = [0, 1, 5, 10, 15];
console.log(values); // [0, 1, 10, 15, 5] 

这个排序明显是不合理的 那么我们可以给sort方法传入一个比较函数

function compare(v1, v2) {
	if (v1 > v2) {
		return 1
	} else if (v1 < v2) {
		return -1
	} else {
		return 0
	}
}
values.sort(compare)
console.log(values); // [0, 1, 5, 10, 15]

简写方法

1.升序排序

values.sort((a, b) => a > b ? 1 : a < b ? -1 : 0);
console.log(values); // [0, 1, 5, 10, 15]

2.降序排序

values.sort((a, b) => a < b ? 1 : a > b ? -1 : 0);
console.log(values); // [15, 10, 5, 1, 0]

3.如果数组元素是数值 或者valueOf()方法返回的是数值 比较函数还可以更简单一些

let compare = (a, b) => a - b;
console.log(values.sort(compare)); // [0, 1, 5, 10, 15] 

7.操作方法

7.1 concat() 复制参数拼接在原数组后返回新数组 [浅拷贝]

7.1.1 语法

var new_array = old_array.concat(value1[, value2[, ...[, valueN]]])

7.1.2 参数

valueN(可选):数组和/或值,将被合并到一个新的数组中。

7.1.3 返回值

新的Array实例

7.1.4 示例
let colors1 = ['red', 'green', 'blue'];
let colors2 = colors1.concat(colors1);
console.log(colors2); 
// ['red', 'green', 'blue','red', 'green', 'blue']

// 为什么传入的二维数组变成了一维数组??
let colors3 = colors1.concat('yellow', ['black', 'white'])
console.log(colors3); // ['red', 'green', 'blue', 'yellow', 'black', 'white']

打平数组参数

let newColors = ['black', 'brown'];
let moreNewColors = {
	[Symbol.isConcatSpreadable]: true,
	length: 2,
  0: 'pink',
  1: 'cyan'
};

newColors[Symbol.isConcatSpreadable] = false

打平数组:如果传入的参数是一个类数组对象 如果不设置Symbol.isConcatSpreadable 则 contact 直接将对象里面的值取出添加给原数组中

// 强制不打平数组
let colors4 = colors1.concat('yellow', newColors);
console.log(colors4); // ['red', 'green', 'blue','yellow', ['black', 'brown']]
// 强制打平类数组对象
let colors5 = colors1.concat(moreNewColors);
console.log(colors5); //  ['red', 'green', 'blue','pink','cyan']

7.2 slice() 返回一个新的数组对象 [浅拷贝]

7.2.1 语法

arr.slice([begin[, end]])

7.2.2 参数

begin:从该索引开始提取原数组元素

end:该索引处结束提取原数组元素

7.2.3 返回值

一个含有被提取元素的新数组

7.2.4 示例
let colors = ['red','green','blue'];
console.log(colors.slice(1)); // ['green','blue']

colors.push('skyblue','pink','black','white');
console.log(colors.slice(1,3)); // ['blue','skyblue','pink']
7.3 splice() 删除或替换现有元素或者原地添加新的元素来修改数组
7.3.1 语法

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

7.3.2 参数

start:指定修改的开始位置

deleteCount:移除的数组元素的个数

item1,item2,...:添加进数组的元素,从start 位置开始 如果不指定 只删除元素

7.3.3 返回值

由被删除的元素组成的一个数组

如果只删除了一个元素,则返回只包含一个元素的数组

如果没有删除元素,则返回空数组

7.3.4 示例
let num = [1, 2, 3, 4, 5, 6];
// 删除元素 传入两个参数 删除第一个元素的位置和删除元素的数量
num.splice(1, 2)
console.log(num); // [1,4,5,6]
// 还原数组
num = [1, 2, 3, 4, 5, 6];

// 添加元素 传入3个参数 开始的位置,0,插入的元素
num.splice(1, 0, 1.3, 1.5, 1.8)
console.log(num); // [1, 1.3, 1.5, 1.8, 2, 3, 4, 5, 6]
// 还原数组
num = [1, 2, 3, 4, 5, 6];

// 替换元素 传入3个参数 开始位置,删除元素的位置 插入任意多个元素
num.splice(1, 3, 2.2, 3.3, 4.4)
console.log(num); // [1, 2.2, 3.3, 4.4, 5, 6]

8.搜索和位置方法

8.1 indexOf() 从0开始查找对应元素的索引值

8.1.1 语法

arr.indexOf(searchElement[, fromIndex])

8.1.2 参数

searchElement:要查找的元素

fromIndex: 开始查找的位置 如果不存在 则返回-1

8.1.3 返回值

找到的元素索引值 未找到返回-1

8.1.4 示例
let num1 = [1, 2, 3, 4, 5, 4, 3, 2, 1];
console.log(num1.indexOf(4)); // 3
console.log(num1.indexOf(4, 6)) // -1

8.2 lastIndexOf() 从length开始查找对应元素的索引值

8.2.1 语法

arr.lastIndexOf(searchElement[, fromIndex])

8.2.2 参数

searchElement:要查找的元素

fromIndex: 开始查找的位置 如果不存在 则返回-1

8.2.3 返回值

找到的元素最后一次出现索引值 未找到返回-1

8.2.4 示例
let num1 = [1, 2, 3, 4, 5, 4, 3, 2, 1];
console.log(num1.lastIndexOf(4)); // 5
console.log(num1.lastIndexOf(4, 2)); // -1

8.3 find() 查找符合函数返回值的数组元素[筛选数组]

8.3.1 语法

arr.find(callback[, thisArg])

8.3.2 参数

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

element: 当前遍历到的元素

index: 索引

arr::当前数组

thisArg: 执行回调时用作this 的对象

8.3.3 返回值

数组中第一个满足所提供测试函数的元素的值,否则返回 undefined

8.3.4 示例
const people1 = [
	{ name: 'cc', age: 18 },
	{ name: 'gg', age: 16 }
];
console.log(people1.find((element, index, array) => { return element.age < 18 })); // {name: 'gg', age: 16}

8.4 findIndex() 符合函数返回值的第一个元素索引

8.4.1 语法

arr.findIndex(callback[, thisArg])

8.4.2 参数

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

element: 当前遍历到的元素

index: 索引

arr::当前数组

thisArg: 执行回调时用作this 的对象

8.4.3 返回值

数组中通过提供测试函数的第一个元素的索引。否则,返回-1

8.4.4 示例
const people1 = [
	{ name: 'cc', age: 18 },
	{ name: 'gg', age: 16 }
];
console.log(people1.findIndex((element, index, array) => { return element.age < 18 })); // 1

注意:这两个方法找到匹配项后 会立即停止函数 不会继续搜索

8.5 includes() 从0开始 判断一个数组是否包含一个指定的值

8.5.1 语法

arr.includes(valueToFind[, fromIndex])

8.5.2 参数

valueToFind:需要查找的元素值

fromIndex(可选):查找开始的索引值

8.5.3 返回值

返回一个布尔值

8.5.4 示例
let num1 = [1, 2, 3, 4, 5, 4, 3, 2, 1];
console.log(num1.includes(4)); // true
console.log(num1.includes(4, 6)); // false

9.迭代方法

语法:

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

参数:

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

element:用于测试的当前值

index:用于测试的当前值的索引

array:调用当前的数组

thisArg:执行 callback 时使用的 this

9.1 every() 一项函数都返回true 则这个方法返回true

9.1.1 返回值

布尔值 全为真值则返回true

9.1.2 示例
let num1 = [1, 2, 3, 4, 5, 4, 3, 2, 1];
console.log(num1.every((item, index, array) => item > 2)); // false

9.2 filter() 过滤数组

9.2.1 返回值

返回过滤后的新数组

9.2.2 示例
console.log(num1.filter((item, index, array) => item > 2)); // [3, 4, 5, 4, 3]

9.3 forEach() 遍历数组

9.3.1 返回值

undefined

9.3.2 示例
num1.forEach((item, index, array) => {
	console.log(item);
});
// 3
// 4
// 5
// 4
// 3

9.4 map() 每个元素执行回调函数的结果组成的新数组

9.4.1 返回值

一个由原数组每个元素执行回调函数的结果组成的新数组

9.4.2 示例
console.log(num1.map((item, index, array) => {
	return item * 2
})); 
// [2, 4, 6, 8, 10, 8, 6, 4, 2]

9.5 some() 有一个函数返回true 则这个方法返回true

9.5.1 返回值

布尔值 一个为真值返回true

9.5.2 示例
console.log(num1.some((item, index, array) => item > 2)); // true

10.归并方法

10.1 reduce()

数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值

reducer 函数接收4个参数:

  1. Accumulator (acc) (累计器/上一个归并值)
  2. Current Value (cur) (当前值)
  3. Current Index (idx) (当前索引)
  4. Source Array (src) (源数组)
10.1.1 语法

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

10.1.2 参数

callback:执行数组中每个值的函数

accumulator:累计器累计回调的返回值

currentValue:数组中正在处理的元素

index(可选):数组中正在处理的当前元素的索引

array(可选):调用该方法的数组

initialValue(可选):作为第一次调用 callback函数时的第一个参数的值

10.1.3 返回值

函数累计处理的结果

10.1.4 示例
let values1 = [1, 2, 3, 4, 5];
console.log(values1.reduce((prev, cur, index, array) => prev + cur));
// 15

10.2 reduceRight()

详细参考reduce()

10.2.1 示例
let values1 = [1, 2, 3, 4, 5];
console.log(values1.reduceRight((prev, cur, index, array) => prev + cur));
// 15