2 回答
TA贡献1909条经验 获得超7个赞
短篇小说
这是引用同一个对象的简单问题。
为了证明这一点,比较两个对象
console.log(firstResultUsing === secondResultUsing)
你会看到它打印true证明它们都引用了同一个对象。
向下滚动以获取解决方案!
长篇大论
在这一行:
const userEmailUsingGenerateSchemaField = generateSchemaField({
user_email: {
type: 'string',
description: 'A user email',
},
})
这里发生的事情是你的generateSchemaField函数正在返回一个函数,它有一个闭包,obj它只是
{
user_email: {
type: 'string',
description: 'A user email',
},
}
现在在这一行:
const firstResultUsing = userEmailUsingGenerateSchemaField()
该函数被评估并返回修改后的对象
{
user_email: {
type: 'string',
description: 'A user email',
required: false
},
}
记住返回的对象仍然具有相同的引用 obj
现在再次在线:
const secondResultUsing = userEmailUsingGenerateSchemaField(true)
这里发生的事情obj是修改了相同的引用对象,并使用属性更新了它required: true
这就是为什么当你们console.log都在展示时,required: true因为他们都引用了同一个对象。
解决方案
const generateSchemaField = obj => {
return function(required = false) {
const objClone = JSON.parse(JSON.stringify(obj));
Object.keys(objClone).forEach(key => {
Object.assign(objClone[key], {
required,
});
});
return objClone;
};
};
让我们分解一下。我删除了,obj = Object.assign({}, obj);因为它没有任何好处。这似乎是一条多余的线。
接下来,我做了一个深克隆的obj。记住Object.assign不会工作,因为它只是创建一个浅拷贝/克隆,在这里它不会工作,因为键email_id持有对对象的引用。请注意,深度克隆JSON.parse(JSON.stringify(obj))仅适用于具有 JSON 安全值(无函数undefined等)的对象。
然后,我操作这个克隆的对象并返回它。现在不存在操作相同引用对象的威胁。
如果这有帮助,或者您需要更好的解释,请告诉我。
添加回答
举报