以纯JS实现常用数组API,揭秘数组底层运作机制
2023-10-31 15:20:53
了解数组的基础知识
数组是一种数据结构,用于存储一组有序的数据项。每个数据项都存储在一个称为元素的单元格中,这些元素可以通过索引来访问。数组是JavaScript中非常重要的数据类型,广泛应用于各种场景,包括存储数据、处理数据以及算法实现等。
实现常见的数组API
为了更好地理解数组的底层机制,我们将使用纯JavaScript实现一些常见的数组API。这些API包括:
Array.from()
Array.of()
Array.prototype.map()
Array.prototype.filter()
Array.prototype.reduce()
Array.prototype.sort()
Array.prototype.splice()
Array.from()
Array.from()
方法将一个类数组对象或可迭代对象转换为真正的数组。它的语法如下:
Array.from(object, mapFn, thisArg)
其中:
object
:要转换的对象。mapFn
:可选的映射函数,用于将每个元素映射到新的数组中。thisArg
:可选的this值,用于执行映射函数。
我们使用纯JavaScript实现Array.from()
方法如下:
function arrayFrom(object, mapFn, thisArg) {
if (!object) {
throw new TypeError('Cannot convert undefined or null to object');
}
const length = object.length;
const result = new Array(length);
for (let i = 0; i < length; i++) {
const value = object[i];
if (mapFn) {
result[i] = mapFn.call(thisArg, value, i, object);
} else {
result[i] = value;
}
}
return result;
}
Array.of()
Array.of()
方法创建一个新的数组,其中包含指定数量的元素。它的语法如下:
Array.of(element1, element2, ..., elementN)
其中,element1
、element2
、...、elementN
是要添加到新数组中的元素。
我们使用纯JavaScript实现Array.of()
方法如下:
function arrayOf(...elements) {
const length = elements.length;
const result = new Array(length);
for (let i = 0; i < length; i++) {
result[i] = elements[i];
}
return result;
}
Array.prototype.map()
Array.prototype.map()
方法创建一个新数组,其中包含对原始数组中每个元素应用指定映射函数的结果。它的语法如下:
array.map(mapFn, thisArg)
其中:
mapFn
:要应用的映射函数。thisArg
:可选的this值,用于执行映射函数。
我们使用纯JavaScript实现Array.prototype.map()
方法如下:
Array.prototype.map = function(mapFn, thisArg) {
const length = this.length;
const result = new Array(length);
for (let i = 0; i < length; i++) {
const value = this[i];
result[i] = mapFn.call(thisArg, value, i, this);
}
return result;
};
Array.prototype.filter()
Array.prototype.filter()
方法创建一个新数组,其中包含通过指定过滤函数测试的原始数组的元素。它的语法如下:
array.filter(filterFn, thisArg)
其中:
filterFn
:要应用的过滤函数。thisArg
:可选的this值,用于执行过滤函数。
我们使用纯JavaScript实现Array.prototype.filter()
方法如下:
Array.prototype.filter = function(filterFn, thisArg) {
const length = this.length;
const result = [];
for (let i = 0; i < length; i++) {
const value = this[i];
if (filterFn.call(thisArg, value, i, this)) {
result.push(value);
}
}
return result;
};
Array.prototype.reduce()
Array.prototype.reduce()
方法对数组中的每个元素执行一个reducer函数,并将结果汇总为一个单一值。它的语法如下:
array.reduce(reducerFn, initialValue)
其中:
reducerFn
:要应用的reducer函数。initialValue
:可选的初始值,用于作为第一次调用reducer函数时的第一个参数。
我们使用纯JavaScript实现Array.prototype.reduce()
方法如下:
Array.prototype.reduce = function(reducerFn, initialValue) {
const length = this.length;
let accumulator = initialValue;
for (let i = 0; i < length; i++) {
const value = this[i];
accumulator = reducerFn(accumulator, value, i, this);
}
return accumulator;
};
Array.prototype.sort()
Array.prototype.sort()
方法对数组中的元素进行排序。它的语法如下:
array.sort(compareFn)
其中:
compareFn
:可选的比较函数,用于确定数组元素的排序顺序。
我们使用纯JavaScript实现Array.prototype.sort()
方法如下:
Array.prototype.sort = function(compareFn) {
const length = this.length;
for (let i = 0; i < length; i++) {
for (let j = i + 1; j < length; j++) {
const a = this[i];
const b = this[j];
const comparisonResult = compareFn ? compareFn(a, b) : a - b;
if (comparisonResult > 0) {
const temp = this[i];
this[i] = this[j];
this[j] = temp;
}
}
}
return this;
};
Array.prototype.splice()
Array.prototype.splice()
方法从数组中添加或删除元素。它的语法如下:
array.splice(start, deleteCount, ...items)
其中:
start
:要开始添加或删除元素的索引。deleteCount
:要删除的元素的数量。items
:要添加到数组中的元素。
我们使用纯JavaScript实现Array.prototype.splice()
方法如下:
Array.prototype.splice = function(start, deleteCount, ...items) {
const length = this.length;
const deletedItems = this.slice(start, start + deleteCount);
const newLength = length - deleteCount + items.length;
const result = new Array(newLength);
for (let i = 0; i < start; i++) {
result[i] = this[i];
}
for (let i = 0; i < items.length; i++) {
result[start + i] = items[i];
}
for (let i = start + deleteCount; i < length; i++) {
result[start + items.length + i - deleteCount] = this[i];
}
this.length = newLength;
return deletedItems;
};
总结
通过实现这些常见的数组API,我们对数组的底层机制有了更深入的理解。这些API为我们提供了对数组进行操作和处理的强大工具,使我们在JavaScript开发中能够更加灵活地应对各种需求。