为什么在 if/else 检查来自 Europeana API 响应的 json 对象时存在不一致?
Why is there inconsistency in if/else checks of json objects from Europeana API response?
有人能解释一下为什么我对某些对象总是出错,而对其他对象却没有吗?
进行 API 调用后,响应返回一个 100 的数组。
items: Array(100)
0:
completeness: 5
country: ["Croatia"]
dataProvider: ["Croatian Academy of Sciences and Arts"]
dcLanguage: ["hr"]
dcLanguageLangAware: {def: Array(1)}
dcSubjectLangAware: {def: Array(2)}
dcTitleLangAware: {def: Array(1)}
dctermsSpatial: (2) ["http://sws.geonames.org/2950159/", "http://data.europeana.eu/place/base/2598"]
并非所有项目都具有相同的属性,但对于具有例如dcSubjectLangAware 我想遍历它们并将变体之一输出到 HTML(en、def 或 de)。如果没有 none 个,输出空字符串。
let dcSubjectLangAware;
if (item.dcSubjectLangAware !== undefined) {
dcSubjectLangAware =
item.dcSubjectLangAware.en ||
item.dcSubjectLangAware.def[0] ||
item.dcSubjectLangAware.hr[0] ||
item.dcSubjectLangAware.def[1] ||
item.dcSubjectLangAware.de[0];
} else {
dcSubjectLangAware = '';
}
当某些项目具有 dcSubjectLangAware 但 none 来自语句的值但例如.it 或 .fr。它没有转到 else 并将空字符串分配给变量,而是抛出无法读取 item.dcSubjectLangAware.def[0] 的错误。当然不能,因为该项目不存在 def[0]。为什么它不循环 item.dcSubjectLangAware.def[1] || item.dcSubjectLangAware.de[0] 然后去else?它对没有任何值的项目(.en、def[0]、def[1] 或 .de[0])执行此操作,但当它偶然发现具有其他值(如 .it[0, 1,2] 或定义为 de 和 en
的多个值
de: (3) ["Deutschland", "Europe", "Travels"]
en: ["Germany"]
它抛出一个错误,而不是从 if/else 中选择一个错误。
Error TypeError: Cannot read property '0' of undefined
at europeana - working.js:73
at Array.forEach (<anonymous>)
at updateUI (europeana - working.js:47)
at europeana - working.js:36
第 73 行来自 if/elseitem.dcSubjectLangAware.def[0]。或者它停留在 item.dcSubjectLangAware.hr[0] 并抛出错误而不检查那里的 item.dcSubjectLangAware.de[0]...
总而言之,它的行为非常不一致。
这里有什么问题?支票应该有所不同吗?
不幸的是,条件 属性 运算符 ?.
在这里也无济于事。你将不得不做这样的事情
let sla=item.dcSubjectLangAware,
dcSubjectLangAware =
sla && (
sla.en ||
sla.def&&sla.def[0] ||
sla.hr&&sla.hr[0] ||
sla.def&&sla.def[1] ||
sla.de&&sla.de[0]
) || 'Description not available.';
澄清一下,Carsten 实施的更彻底的检查是必要的,即您必须检查是否有 .hr 属性,然后还有 .hr[0] 等等。
为了其他人和可读性,这里是if/else方式:
let dcSubjectLangAware;
if (item.dcSubjectLangAware !== undefined) {
dcSubjectLangAware =
(item.dcSubjectLangAware && item.dcSubjectLangAware.en) ||
(item.dcSubjectLangAware.def && item.dcSubjectLangAware.def[0]) ||
(item.dcSubjectLangAware.hr && item.dcSubjectLangAware.hr[0]) ||
(item.dcSubjectLangAware.def && item.dcSubjectLangAware.def[1]) ||
(item.dcSubjectLangAware.de && item.dcSubjectLangAware.de[0]);
} else {
dcSubjectLangAware = 'Description not available.';
}
可以遍历候选语言键的数组 find
元数据 LangMap 中存在的第一个,例如item.dcSubjectLangAware
,return 它的第一个值。
作为可能在其他元数据字段上重用的函数:
const localiseLangMap = (langMap, languages) => {
let localised = '';
if (langMap) {
const language = languages.find(lang => langMap[lang]);
if (language) {
localised = langMap[language][0];
}
}
return localised;
};
const languages = ['en', 'def', 'de'];
const dcSubjectLangAware = localiseLangMap(item.dcSubjectLangAware, languages);
有人能解释一下为什么我对某些对象总是出错,而对其他对象却没有吗? 进行 API 调用后,响应返回一个 100 的数组。
items: Array(100)
0:
completeness: 5
country: ["Croatia"]
dataProvider: ["Croatian Academy of Sciences and Arts"]
dcLanguage: ["hr"]
dcLanguageLangAware: {def: Array(1)}
dcSubjectLangAware: {def: Array(2)}
dcTitleLangAware: {def: Array(1)}
dctermsSpatial: (2) ["http://sws.geonames.org/2950159/", "http://data.europeana.eu/place/base/2598"]
并非所有项目都具有相同的属性,但对于具有例如dcSubjectLangAware 我想遍历它们并将变体之一输出到 HTML(en、def 或 de)。如果没有 none 个,输出空字符串。
let dcSubjectLangAware;
if (item.dcSubjectLangAware !== undefined) {
dcSubjectLangAware =
item.dcSubjectLangAware.en ||
item.dcSubjectLangAware.def[0] ||
item.dcSubjectLangAware.hr[0] ||
item.dcSubjectLangAware.def[1] ||
item.dcSubjectLangAware.de[0];
} else {
dcSubjectLangAware = '';
}
当某些项目具有 dcSubjectLangAware 但 none 来自语句的值但例如.it 或 .fr。它没有转到 else 并将空字符串分配给变量,而是抛出无法读取 item.dcSubjectLangAware.def[0] 的错误。当然不能,因为该项目不存在 def[0]。为什么它不循环 item.dcSubjectLangAware.def[1] || item.dcSubjectLangAware.de[0] 然后去else?它对没有任何值的项目(.en、def[0]、def[1] 或 .de[0])执行此操作,但当它偶然发现具有其他值(如 .it[0, 1,2] 或定义为 de 和 en
的多个值de: (3) ["Deutschland", "Europe", "Travels"]
en: ["Germany"]
它抛出一个错误,而不是从 if/else 中选择一个错误。
Error TypeError: Cannot read property '0' of undefined
at europeana - working.js:73
at Array.forEach (<anonymous>)
at updateUI (europeana - working.js:47)
at europeana - working.js:36
第 73 行来自 if/elseitem.dcSubjectLangAware.def[0]。或者它停留在 item.dcSubjectLangAware.hr[0] 并抛出错误而不检查那里的 item.dcSubjectLangAware.de[0]...
总而言之,它的行为非常不一致。 这里有什么问题?支票应该有所不同吗?
不幸的是,条件 属性 运算符 ?.
在这里也无济于事。你将不得不做这样的事情
let sla=item.dcSubjectLangAware,
dcSubjectLangAware =
sla && (
sla.en ||
sla.def&&sla.def[0] ||
sla.hr&&sla.hr[0] ||
sla.def&&sla.def[1] ||
sla.de&&sla.de[0]
) || 'Description not available.';
澄清一下,Carsten 实施的更彻底的检查是必要的,即您必须检查是否有 .hr 属性,然后还有 .hr[0] 等等。
为了其他人和可读性,这里是if/else方式:
let dcSubjectLangAware;
if (item.dcSubjectLangAware !== undefined) {
dcSubjectLangAware =
(item.dcSubjectLangAware && item.dcSubjectLangAware.en) ||
(item.dcSubjectLangAware.def && item.dcSubjectLangAware.def[0]) ||
(item.dcSubjectLangAware.hr && item.dcSubjectLangAware.hr[0]) ||
(item.dcSubjectLangAware.def && item.dcSubjectLangAware.def[1]) ||
(item.dcSubjectLangAware.de && item.dcSubjectLangAware.de[0]);
} else {
dcSubjectLangAware = 'Description not available.';
}
可以遍历候选语言键的数组 find
元数据 LangMap 中存在的第一个,例如item.dcSubjectLangAware
,return 它的第一个值。
作为可能在其他元数据字段上重用的函数:
const localiseLangMap = (langMap, languages) => {
let localised = '';
if (langMap) {
const language = languages.find(lang => langMap[lang]);
if (language) {
localised = langMap[language][0];
}
}
return localised;
};
const languages = ['en', 'def', 'de'];
const dcSubjectLangAware = localiseLangMap(item.dcSubjectLangAware, languages);