在 js 中,除了 Object,Array 应该就是 ECMAScript 中最常用的类型了。
一、创建数组,共两种方法,加上一种转化方法。
a. 构建函数创建
let a1 = new Array(); // []
let a2 = new Array(20); // [empty × 20]
let colors = new Array("red", "blue", "green"); // ['red', 'blue', 'green']
let nums = new Array(1,3,5); // [1, 3, 5]
在使用 Array 构造函数时,也可以省略 new 操作符。结果是一样的,比如:
let colors = Array(3); // 创建一个包含 3 个元素的数组
let names = Array("Greg"); // 创建一个只包含一个元素,即字符串"Greg"的数组
new操作符的作用:
(1) 在内存中创建一个新对象。
(2) 这个新对象内部的[[Prototype]]特性被赋值为构造函数的 prototype 属性。
(3) 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。
(4) 执行构造函数内部的代码(给新对象添加属性)。
(5) 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
JavaScript构造函数new与不new的区别
任何函数只要使用 new 操作符调用就是构造函数,而不使用 new 操作符调用的函数就是普通函数。
其次,对于js内置的一些构造函数,例如Array、Object等,如果没有加new操作符,其内部会判断是否加上new关键字。
若是普通的构造函数,当我们不加new关键字的时候,此时this指向的是globalthis全局对象。
b. 数组字面量表示法
let colors = ["red", "blue", "green"]; // 创建一个包含 3 个元素的数组
let names = []; // 创建一个空数组
let values = [1,2,]; // 创建一个包含 2 个元素的数组
c. 静态方法创建数组
Array 构造函数还有两个 ES6 新增的用于创建数组的静态方法:from()和 of()。from()用于将类数组结构转换为数组实例,而 of()用于将一组参数转换为数组实例。
Array.from()
第一个参数是一个类数组对象,即任何可迭代的结构,或者有一个 length 属性和可索引元素的结构。
第二个可选的映射函数参数,这个函数可以直接增强新数组的值。<br/>
第三个可选参数,用于指定映射函数中 this 的值。但这个重写的 this 值在箭头函数中不适用。
const a1 = [1, 2, 3, 4];
const a2 = Array.from(a1, x => x**2);
const a3 = Array.from(a1, function(x) {return x**this.exponent}, {exponent: 2});
console.log(a2); // [1, 4, 9, 16]
console.log(a3); // [1, 4, 9, 16]
Array.of()
Array.of()可以把一组参数转换为数组。这个方法用于替代在 ES6之前常用的 Array.prototype.slice.call(arguments),
一种异常笨拙的将 arguments 对象转换为数组的写法:
console.log(Array.of(1, 2, 3, 4)); // [1, 2, 3, 4]
console.log(Array.of(undefined)); // [undefined]
二、数组空位
使用数组字面量初始化数组时,可以使用一串逗号来创建空位(hole)。
const options = [,,,,,]; // 创建包含 5 个元素的数组
console.log(options.length); // 5
console.log(options); // [,,,,,]
ES6 之前的方法则会忽略这个空位,但具体的行为也会因方法而异:
const options = [1,,,,5];
// map()会跳过空位置
console.log(options.map(() => 6)); // [6, undefined, undefined, undefined, 6]
// join()视空位置为空字符串
console.log(options.join('-')); // "1----5"
注意:
由于行为不一致和存在性能隐患,因此实践中要避免使用数组空位。如果确实需要空位,则可以显式地用 undefined 值代替。
三、 数组方法
1、检测数组方法:
if (value instanceof Array){
// 操作数组
}
if (Array.isArray(value)){
// 操作数组
}
2、迭代器方法:
const a = ["foo", "bar", "baz", "qux"];
// 因为这些方法都返回迭代器,所以可以将它们的内容
// 通过 Array.from()直接转换为数组实例
const aKeys = Array.from(a.keys());
const aValues = Array.from(a.values());
const aEntries = Array.from(a.entries());
console.log(aKeys); // [0, 1, 2, 3]
console.log(aValues); // ["foo", "bar", "baz", "qux"]
console.log(aEntries); // [[0, "foo"], [1, "bar"], [2, "baz"], [3, "qux"]]
3、填充方法:fill()
const zeroes = [0, 0, 0, 0, 0];
// 用 5 填充整个数组
zeroes.fill(5);
console.log(zeroes); // [5, 5, 5, 5, 5]
zeroes.fill(0);
// 用 7 填充索引大于等于 1 且小于 3 的元素
zeroes.fill(7, 1, 3);
console.log(zeroes); // [0, 7, 7, 0, 0];
4、复制方法:copyWithin()
let ints = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
ints.copyWithin(4, 0, 3);
alert(ints); // [0, 1, 2, 3, 0, 1, 2, 7, 8, 9]
5、转换方法
let colors = ["red", "blue", "green"]; // 创建一个包含 3 个字符串的数组
alert(colors.toString()); // red,blue,green
alert(colors.join()); // red,green,blue
alert(colors.join("||")); // red||green||blue
6、栈方法
ECMAScript 数组提供了 push()和 pop()方法,以实现类似栈的行为。
7、队列方法
使用 shift()和 push(),可以把数组当成队列来使用。
使用 unshift()和 pop(),可以在相反方向上模拟队列。
8、排序方法
数组有两个方法可以用来对元素重新排序:reverse()和 sort()。
9、操作方法
concat()
可以在现有数组全部元素基础上创建一个新数组。它首先会创建一个当前数组的副本,然后再把它的参数添加到副本末尾,最后返回这个新构建的数组。
let colors = ["red", "green", "blue"];
let colors2 = colors.concat("yellow", ["black", "brown"]);
console.log(colors); // ["red", "green","blue"]
console.log(colors2); // ["red", "green", "blue", "yellow", "black", "brown"]
slice()
用于创建一个包含原有数组中一个或多个元素的新数组。
可以接收一个或两个参数:返回元素的开始索引和结束索引。
let colors = ["red", "green", "blue", "yellow", "purple"];
let colors2 = colors.slice(1);
let colors3 = colors.slice(1, 4);
alert(colors2); // green,blue,yellow,purple
alert(colors3); // green,blue,yellow
splice()
最强大的数组方法,主要目的是在数组中间插入元素,但有 3 种不同的方式(删除、插入、替换)使用这个方法。
删除:
let colors = ["red", "green", "blue"];
let removed = colors.splice(0,1); // 删除第一项
alert(colors); // green,blue
alert(removed); // red,只有一个元素的数组
插入:
removed = colors.splice(1, 0, "yellow", "orange"); // 在位置 1 插入两个元素
alert(colors); // green,yellow,orange,blue
alert(removed); // 空数组
替换:
removed = colors.splice(1, 1, "red", "purple"); // 插入两个值,删除一个元素
alert(colors); // green,red,purple,orange,blue
alert(removed); // yellow,只有一个元素的数组
10、搜索和位置方法
ECMAScript 提供了 3 个严格相等的搜索方法:indexOf()、lastIndexOf()和 includes()。
find()和 findIndex()方法使用了断言函数。这两个方法都从数组的最小索引开始。
find()返回第一个匹配的元素,findIndex()返回第一个匹配元素的索引。
const people = [{name: "Matt",age: 27},{name: "Nicholas",age: 29}];
alert(people.find((element, index, array) => element.age < 28));
// {name: "Matt", age: 27}
alert(people.findIndex((element, index, array) => element.age < 28));
// 0
11、迭代方法
every():对数组每一项都运行传入的函数,如果对每一项函数都返回 true,则这个方法返回 true。
filter():对数组每一项都运行传入的函数,函数返回 true 的项会组成数组之后返回。
forEach():对数组每一项都运行传入的函数,没有返回值。在forEach中并不能直接使用break、continue。
map():对数组每一项都运行传入的函数,返回由每次函数调用的结果构成的数组。
some():对数组每一项都运行传入的函数,如果有一项函数返回 true,则这个方法返回 true。
这些方法都不改变调用它们的数组。
12、归并方法
ECMAScript 为数组提供了两个归并方法:reduce()和 reduceRight()。
let values = [1, 2, 3, 4, 5];
let sum = values.reduce((prev, cur, index, array) => prev + cur);
alert(sum); // 15