查看原文
其他

从零开始实现数组方法来学习JavaScript,编码面试题

Dunizb 前端全栈开发者 2022-07-09

本文将介绍一些JavaScript数组问题,通过从零开始实现数组方法来学习更多关于JavaScript数组的知识,并练习使用它们进行常见的操作。

手动实现Array.prototype.map方法

Array.prototype.map 方法通过调用一个回调函数来进行映射,从而将每个数组项映射到新的项。它返回一个带有映射值的新数组。使用如下

let result = arr.map(function(item, index, array) {
// 返回新值而不是当前元素
})

我们可以实现它如下:

const map = (arr, callback) => {
if (!Array.isArray(arr)) {
return [];
}
const newArr = [];
for (let i = 0, len = arr.length; i < len; i++) {
newArr.push(callback(arr[i], i, arr));
}
return newArr;
}

首先,我们检查 arr 是否为数组,如果不是,则返回一个空数组。

在上面的代码中,我们有 map 方法,它循环遍历每个数组项,并使用数组项、索引和传入的原始数组调用回调,每个条目都被推送到 newArr 数组。

然后它返回 newArr 数组,其中包含映射的项。

手动实现Array.prototype.filter方法

Array.prototype.filter 方法返回一个新数组,该数组从满足回调条件的原始数组中获取元素,将这些条目推入一个新数组,然后返回,使用如下:

let results = arr.filter(function(item, index, array) {
// 如果 true item 被 push 到 results,迭代继续
// 如果什么都没找到,则返回空数组
});

我们可以如下实现:

const filter = (arr, callback) => {
if (!Array.isArray(arr)) {
return [];
}
const newArr = [];
for (let i = 0, len = arr.length; i < len; i++) {
if (callback(arr[i], i, arr)) {
newArr.push(arr[i]);
}
}
return newArr;
}

在上面的代码中,我们首先检查 arr 是否为数组。如果不是,我们将返回一个空数组。然后我们循环遍历 arr,然后使用 if 块来检查回调调用是否返回 true,然后将这些条目推到 newArr 并返回它。

手动实现Array.prototype.reduce方法

Array.prototype.reduce 方法通过重复调用回调以将数组项组合为一个值,从而将数组的项组合为一个。使用如下

let value = arr.reduce(function(accumulator, item, index, array) {
// ...
}, [initial]);

该函数一个接一个地应用于所有数组元素,并将其结果“搬运”到下一个调用。

参数:

  • accumulator – 是上一个函数调用的结果,第一次等于 initial(如果提供了 initial 的话)。
  • item — 当前的数组元素。
  • index — 当前索引。
  • arr — 数组本身。

我们可以如下实现:

const reduce = (arr, reduceCallback, initialValue) => {
if (!Array.isArray(arr)) {
return;
}
let val = initialValue || 0;
for (let i = 0, len = arr.length; i < len; i++) {
val = reduceCallback(val, arr[i]);
}
return val;
}

我们首先检查 arr 是否是数组,然后我们遍历数组,使用 reduceCallback 组合 valarr[i] 并返回新值并将其分配给 val

循环完成后,我们返回 val

arguments对象是什么?

arguments 对象是一个类似数组的对象,它返回传递给传统函数的参数。

它不适用于箭头函数。

这是一个类似数组的对象,因为它的项可以由索引访问,并且具有 length 属性。arguments 没有数组方法。

而且,它可以通过 for…of 并被转换为一个具有扩展操作符的数组。

例如,如果我们写:

function logArgs() {
console.log(arguments)
}
logArgs(1, 2, 3, 4, 5);
// Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]

我们可以看到项和 Symbol.iterator 迭代器方法,我们知道它是一个可迭代的对象。

我们可以使用扩展运算符将其转换为数组,如下所示:

function logArgs() {
console.log([...arguments])
}
logArgs(1, 2, 3, 4, 5);
// [1,2,3,4,5]

然后 console.log 给出 [1,2,3,4,5] ,这是一个常规数组。

对于箭头函数,我们使用rest运算符来获取所有参数,如下所示:

const logArgs = (...args) => {
console.log(args)
}
logArgs(1, 2, 3, 4, 5);
// [1, 2, 3, 4, 5]

如何在数组的开头添加元素?

我们可以使用 Array.prototype.unshift 方法将元素添加到数组的开头。

例如,我们可以这样写:

const arr = [2, 3, 4];
arr.unshift(1);
// [1,2,3,4]

扩展操作符也可以实现:

letarr = [2, 3, 4];
arr.unshift(1, ...arr);
// [1,2,3,4]

请注意,由于我们分配了一个新值,因此将 const 更改为 let

如何在数组末尾添加元素?

我们可以使用 push 方法将条目添加到数组的末尾。

const arr = [2, 3, 4];
arr.push(1);
// [2, 3, 4, 1]

扩展操作符也可以实现:

let arr = [2, 3, 4];
arr = [...arr, 1];

请注意,由于我们分配了一个新值,因此将 const 更改为 let。


近期推荐:


感谢您的阅读和关注,看完三件事:
如果对你有帮助,帮忙文章右下角点个在看如果有什么问题欢迎留言交流,还可以转发,这是对作者最大的帮助。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存