我有一个具有各种键值的对象(简化):
const params = {
dev: {
api: {},
iot: {},
},
test: {
api: {},
iot: {},
}
};
我希望填充Object.keys().forEach
函数:
Object.keys(params).forEach(key => {
params[key].iot.keyName = `/firstURL/`;
params[key].api.anotherKeyName = `/url/var2`;
});
目前,这会按预期填充,但如果我从params对象中删除键(API / IOT),则会出现undefined
错误。
我的想法是检查密钥是否首先定义,如果不是(实际上永远不会定义),请使用默认值:
Object.keys(params).forEach(key => {
params[key].iot.keyName = params[key].iot.keyName || `/firstURL/`;
params[key].api.anotherKeyName = params[key].api.anotherKeyName || `/url/var2`;
});
我从params
对象中删除密钥的原因是,它们总是在运行中生成(取决于您所使用的内容)。
为什么我检查keyName
是否为未定义错误,当我检查它是否存在时,如果没有,请为其分配值?
非常感谢。
答案 0 :(得分:1)
为什么我得到keyName是未定义的错误,当我检查它时 是否存在,如果没有,为其分配值?
您没有收到keyName
为undefined
的消息。仔细观察,消息显示Cannot read property 'keyName' of undefined"
。
const params = {
dev: {},
test: {}
};
Object.keys(params).forEach(key => {
params[key].iot.keyName = params[key].iot.keyName || `/firstURL/`;
params[key].api.anotherKeyName = params[key].api.anotherKeyName || `/url/var2`;
});

它没有抱怨keyName
。它抱怨您无法通过undefined
的其他内容阅读该属性 - 事情是iot
。
您正在检查是否存在keyName
并为其设置默认值(如果它不存在),但这不是问题。 问题是iot
不存在。
您收到错误的原因是,虽然您可以通过为其分配值来创建新属性,但您无法访问不存在的属性上的属性以及您正在使用的属性:
params[key].iot.keyName = `/firstURL/`;
如果iot
不存在,则无法访问iot.keyName
。
举例说明:
var obj = {};
obj.key1 = "foo"; // works
obj.key2.subKey = "bar"; // fails because key2 doesn't exist so bar can't be created on it

在访问属性的属性之前,您需要添加一些检查以查看属性是否存在。这是一个例子:
var obj = {};
obj.key1 = "foo"; // works
if(obj.key2){
obj.key2.subKey = "bar"; // works when key2 exists
} else {
obj.key2 = {}; // Create the key
obj.key2.subKey = "bar"; // Now, you can access it and make sub-keys
}
console.log(obj);

一种简单的思考方式是与几代人的类比。
params
是第一代iot
是第二代(params
的孩子)keyName
是第三代(iot
的孩子和孙子
params
)与现实世界一样,如果你没有孩子,你就不能为你的孙子照看孩子。孩子们必须先来。当没有孩子时,你的代码会尝试与孙子一起工作。
答案 1 :(得分:1)
目前,这会按预期填充,但如果我从params对象中删除键(API / IOT),则会出现未定义的错误。
(我的重点)
当然。您的代码不会以任何方式检查以确保它们首先存在。要做到这一点:
Object.keys(params).forEach(key => {
if (params[key].iot) params[key].iot.keyName = `/firstURL/`;
if (params[key].api) params[key].api.anotherKeyName = `/url/var2`;
});
旁注:您可以查看Object.values
,在ES2017中添加,但完全可以填充:
Object.values(params).forEach(entry => {
if (entry.iot) entry.iot.keyName = `/firstURL/`;
if (entry.api) entry.api.anotherKeyName = `/url/var2`;
});