1. 创建数组
1.1 Array.of() 方法
let items = new Array(2);
console.log(items.length); // 2
console.log(items[0]); // undefined
console.log(items[1]); // undefined
items = new Array("2");
console.log(items.length); // 1
console.log(items[0]); // "2"
items = new Array(1, 2);
console.log(items.length); // 2
console.log(items[0]); // 1
console.log(items[1]); // 2
items = new Array(3, "2");
console.log(items.length); // 2
console.log(items[0]); // 3
console.log(items[1]); // "2"
使用的都是构造函数,但是传入不同参数造成的结果不同。这种行为既混乱又有风险,因此引入了Array.of() 方法.类似于使用数组字面量写法
let items = Array.of(1, 2);
console.log(items.length); // 2
console.log(items[0]); // 1
console.log(items[1]); // 2
items = Array.of(2);
console.log(items.length); // 1
console.log(items[0]); // 2
items = Array.of("2");
console.log(items.length); // 1
console.log(items[0]); // "2"
Array.of() 方法并没有使用 Symbol.species 属性来决定返回值的类型,而是使用了当前的构造器(即 of() 方法内部的 this )来做决定。
1.2 Array.from()
1.2.1 类数组转数组
在 JS 中将非数组对象转换为真正的数组总是很麻烦。例如,若想将类数组的 arguments 对象当做数组来使用,那么你首先需要对其进行转换。
版本一、
function makeArray(arrayLike) {
var result = [];
for (var i = 0, len = arrayLike.length; i < len; i++) {
result.push(arrayLike[i]);
}
return result;
}
function doSomething() {
var args = makeArray(arguments);
// 使用 args
}
版本二、
function makeArray(arrayLike) {
return Array.prototype.slice.call(arrayLike);
}
function doSomething() {
var args = makeArray(arguments);
// 使用 args
}
版本三、
function doSomething() {
var args = Array.from(arguments);
// 使用 args
}
版本四、
进一步的数组转换向 Array.from() 方法传递一个映射用的函数作为第二个参数。
function translate() {
return Array.from(arguments, (value) => value + 1);
}
let numbers = translate(1, 2, 3);
console.log(numbers);
版本五、
动传递第三个参数可以指定映射函数内部的 this 值
let helper = {
diff: 1,
add(value) {
return value + this.diff;
}
};
function translate() {
return Array.from(arguments, helper.add, helper);
}
let numbers = translate(1, 2, 3);
console.log(numbers);
1.2.2 可迭代对象转数组
Array.from() 方法不仅可用于类数组对象,也可用于可迭代对象,可以将任意包含 Symbol.iterator 属性的对象转换为数组。
let numbers = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
let numbers2 = Array.from(numbers, (value) => value + 1);
console.log(numbers2);
2. 所有数组上的新方法
2.1 find() 与 findIndex() 方法
find() 与 findIndex() 方法均接受两个参数:一个回调函数、一个可选值用于指定回调函数内部的 this
数组.find((item, index, _self) => {}, this);
数组.findIndex((item, index, _self) => {}, this);
eg:
let numbers = [25, 30, 35, 40, 45];
console.log(numbers.find(n => n > 33)); // 35
console.log(numbers.findIndex(n => n > 33));
find() 与 findIndex() 方法在查找满足特定条件的数组元素时非常有用。但若想查找特定值,则使用 indexOf() 与 lastIndexOf() 方法会是更好的选择。
2.2 fill() 方法
fill() 方法能使用特定值填充数组中的一个或多个元素。当只使用一个参数的时候,该方法会用该参数的值填充整个数组,(填充值,起始位置, 结束位置)
let numbers = [1, 2, 3, 4];
numbers.fill(1);
console.log(numbers.toString()); // 1,1,1,1
let numbers = [1, 2, 3, 4];
numbers.fill(1, 2);
console.log(numbers.toString()); // 1,2,1,1
numbers.fill(0, 1, 3);
console.log(numbers.toString()); // 1,0,0,1
2.3 copyWithin() 方法
copyWithin() 方法:从什么位置开始进行填充,以及被用来复制的数据的起始位置索引。以提供一个可选参数来限制到底有多少元素会被覆盖。
let numbers = [1, 2, 3, 4];
// 从索引 2 的位置开始粘贴
// 从数组索引 0 的位置开始复制数据
numbers.copyWithin(2, 0);
console.log(numbers.toString());
let numbers2 = [1, 2, 3, 4];
// 从索引 2 的位置开始粘贴
// 从数组索引 0 的位置开始复制数据
// 在遇到索引 1 时停止复制
numbers2.copyWithin(2, 0, 1);
console.log(numbers2.toString()); // 1,2,1,4
3. 类型化数组
3.1 数值数据类型
- 8 位有符号整数(int8)
- 8 位无符号整数(uint8)
- 16 位有符号整数(int16)
- 16 位无符号整数(uint16)
- 32 位有符号整数(int32)
- 32 位无符号整数(uint32)
- 32 位浮点数(float32)
- 64 位浮点数(float64)
3.2 数组缓冲区
let buffer = new ArrayBuffer(10); // 分配了 10 个字节
let buffer2 = buffer.slice(4, 6); // slice() 方法来创建一个新的、包含已有缓冲区部分内容的数组缓冲区
console.log(buffer2.byteLength);
4. 类型化数组与常规数组的相似点
4.1 公共方法
copyWithin()、entries()、fill()、filter()、find()、findIndex()、forEach()、indexOf()、join()、keys()、lastIndexOf()、map()、reduce()、reduceRight()、reverse()、slice()、some()、sort()、values()
4.2 相同的迭代器
entries() 方法、 keys() 方法与values() 方法。
4.3 of() 与 from() 方法
let ints = Int16Array.of(25, 50),
floats = Float32Array.from([1.5, 2.5]);
console.log(ints instanceof Int16Array); // true
console.log(floats instanceof Float32Array); // true
5. 类型化数组与常规数组的区别
类型化数组并不是从 Array 对象派生的,使用 Array.isArray() 去检测会返回false
5.1 行为差异
1、常规数组可以被伸展或是收缩,然而类型化数组却会始终保持自身大小不变。可以对常规数组一个不存在的索引位置进行赋值,但在类型化数组上这么做则会被忽略。
let ints = new Int16Array([25, 50]);
console.log(ints.length); // 2
console.log(ints[0]); // 25
console.log(ints[1]); // 50
ints[2] = 5;
console.log(ints.length); // 2
console.log(ints[2]); // undefined
2、类型化数组也会对数据类型进行检查以保证只使用有效的值,当无效的值被传入时,将会被替换为 0
let ints = new Int16Array(["hi"]);
console.log(ints.length); // 1
console.log(ints[0]); // 0
5.2 遗漏的方法
concat()、pop()、push()、shift()、splice()、unshift()
5.3 附加的方法
set()从另一个数组中复制元素到当前的类型化数组
subarray()是将当前类型化数组的一部分提取为新的类型化数组
let ints = new Int16Array(4);
ints.set([25, 50]);
ints.set([75, 100], 2);
console.log(ints.toString()); // 25,50,75,100
let ints = new Int16Array([25, 50, 75, 100]),
subints1 = ints.subarray(),
subints2 = ints.subarray(2),
subints3 = ints.subarray(1, 3);
console.log(subints1.toString()); // 25,50,75,100
console.log(subints2.toString()); // 75,100
console.log(subints3.toString()); // 50,75
网友评论