JavaScript 面试:创建对象的深层复制
这个系列讲的是什么?
这个系列讲的是什么?
大家好!欢迎来到 JavaScript 面试问答系列。在本系列的每一篇文章中,我都会讨论我在最近面试中遇到的(特定于 JavaScript 的)问题。如果你正在准备 JavaScript 面试,或者刚刚开始深入学习 JavaScript 并想测试一下你的知识,本系列文章将会对你有所帮助。
帖子 1:创建对象的深层副本
我们当中许多参与过大型业余项目或为其他业余项目做过贡献的人一定都接触过像 Lodash.js、Underscore.js 这样的 JavaScript 辅助库。这些库为我们提供了 JavaScript 内置函数之外的功能。其中之一就是在 JavaScript 中复制对象。我们很多人都知道如何通过对象析构来复制只有一层嵌套的对象。但是,如果你的对象包含多层嵌套,JavaScript 中就没有内置的方法来复制该对象。
很多人可能想知道为什么要问这个问题?如果我们有辅助库,为什么不直接用呢?你说得完全正确。我们应该用,而且我们确实用过。但是编写这样一个核心函数会考验你如何从根本上理解和运用知识。正如我们稍后将在本文看到的,这个问题考察你如何运用已有的知识。所以,让我们进入解决问题的模式👨💻⚔️。
问题陈述
编写一个函数,将一个对象作为参数并返回该对象的深层副本。
// Signature
function copyObject(source) {
}
// Usage
const source = {
a: 10,
b: 20,
c: {
d: 30
}
}
const target = copyObject(source);
在深入研究解决方案之前,我强烈建议您尝试自己解决这个问题。以下是一些提示:
- 忘掉嵌套部分吧。首先,只需尝试复制每个键和值即可。
- 现在考虑如何识别一个值本身是否是一个对象以及如何处理它。
解决方案
我在解决任何问题时,总是喜欢先写那些显而易见的东西。这些东西可以通过仔细阅读问题描述来找到。问题要求返回一个对象,这是显而易见的。所以,我们先把它写下来。
function copyObject(source) {
var target = {};
return target;
}
现在,问题要求我们对对象进行深层复制。但在直接进行深层复制之前,我们先写一个简单的解决方案,用于复制单层嵌套中的每个键值。那么,我们需要做什么呢?
- 我们需要源对象的所有键
- 在目标对象中逐个添加所有这些键。
function copyObject(source) {
var target = {};
const keys = Object.keys(source);
keys.forEach(key => {
target[key] = source[key];
});
return target;
}
太棒了!我们已经解决了最简单用例的问题。现在让我们考虑一下嵌套。首先,我们如何知道当前键对应的值本身是否是一个对象?通过使用typeof
运算符。当我们知道当前值是一个对象时,我们如何获取它的副本?——>通过使用我们正在编写的函数。我知道这现在听起来可能令人困惑。这种技术称为递归(您可以在此处了解有关递归的更多信息)。我们只需编写代码,您就会明白。因此,问题的最终解决方案将如下所示:
function copyObject(source) {
var target = {};
// Getting source object keys
const keys = Object.keys(source);
keys.forEach(key => {
// Checking if current value is an object
if (typeof source[key] === "object") {
// Calling our function recursively for current value
target[key] = copyObject(source[key]);
} else {
// Directly assigning the value
target[key] = source[key];
}
});
return target;
}
结论
太棒了!!现在看起来是个可行的解决方案。但是这个方案仍然存在一些小问题,比如处理对象中的数组和函数值。我鼓励你编写处理这些问题的代码,并将其发布在评论区。想要了解更多类似的有趣问题,请继续关注本系列。在此之前,祝你编码愉快!
文章来源:https://dev.to/amitkhonde/javascript-interviews-create-a-deep-copy-of-an-object-4pje