如何将一个对象的匹配属性复制到另一个对象?

22

我有这两个对象:

obj1 = {a: '', b: ''}
obj2 = {a: '1', b: '2', c: '3'}

我想将obj2中所有匹配属性复制到obj1。在TypeScript中最好的方法是什么?


1
可能是JavaScript中深度克隆对象的最有效方法是什么?的重复问题。 - Michael Freidgeim
4个回答

18

在TypeScript中最好的做法是什么?

与JavaScript相同,只需使用Object.keys

以下代码将内容从obj2移动到obj1:

let obj1 = {a: '', b: ''}
let obj2 = {a: '1', b: '2', c: '3'}

Object.keys(obj2).forEach(key=>obj1[key]=obj2[key]);

对于任何条件,例如“必须尚未在obj1中”,等等,您可以在forEach中进行检查。


3
你不觉得应该有一个条件语句来检查obj1中是否存在键吗,例如obj1.hasOwnProperty(key)? - Ajay
@basarat,你有没有相同的仅复制匹配属性但进行深度遍历的方法?当我从某些本地存储中加载用户设置结构时,总是遇到这个问题。我想从最新的带有默认值的对象结构开始,并且只递归地复制来自存储加载的对象中匹配键的值。我似乎找不到正确的文章。谢谢。 - Meryan
2
此答案中的代码不完整,因为它忽略了 OP 的请求仅复制匹配的属性。应添加以下内容:if (key in obj1) - OfirD
7
或许 TSC 变得更加严格了,但我对这段代码出现类型错误(ts:7053)感到困惑,它抱怨对象类型上没有索引器。 - Krisztián Balla
TSC 的严格性是一个选项。 - bikeman868

16
如果您不介意obj2中的任何键不存在于obj1中,那么更清晰的方法是使用Object.assign(obj1, obj2)

2
我觉得@basarat的意思是要像这样遍历目标属性,而不是源属性。
function CopyMatchingKeyValues(Target, Source) {
    return Object.keys(Target).forEach(key => {
        if (Source[key] !== undefined)
            Target[key] = Source[key];
    });
}

enter image description here

其实他是在测试关键匹配,这并不重要。
为了性能,我们可能希望选择最短的关键字列表。

11
请将代码以文本而非图片的形式发布。 - DBS
4
这个错误提示的意思是:ts:7053 行代码处出现了一个问题。因为使用了一个字符串类型的表达式来索引一个类型,所以该元素的类型隐含地被推断为 'any'。意味着在此类型中没有找到带有 'string' 类型参数的索引签名。 - Krisztián Balla

1
我能满足TS编译器的唯一方法就是像下面这样,但是每次看到这个我都觉得眼睛要流血了。
Object.keys(source).forEach(key => {
    if (destination.hasOwnProperty(key))
        destination[key as keyof Destination] = source[key as keyof Source] as never;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接