我正在尝试使用for循环获取对象的JSON数组,但是由于某些原因,它只有在我将索引显式传递为数字(例如parseJSON.sites[0]
)时才有效。如果使用变量,由于循环的缘故,在本示例中我希望使用该变量,则显示的示例将不起作用。
let openJSON = fs.readFileSync('./pages/jsons/main.json', 'utf-8');
let parseJSON = JSON.parse(openJSON);
for (let i = 0; i <= 4; i++) {
//this code doens't work and return: Cannot read property 'name' of undefined
main.push(parseJSON.sites[i]["name"]);
//this code works, and returns what i expected
main.push(parseJSON.sites[0]["name"]);
}
//main.json
{
"sites": [
{ "name": "stackoverflow", "url": "stackoverflow.com" },
{ "name": "Youtube", "url": "www.youtube.com" },
]
}
我不知道为什么这段代码不起作用。我已经尝试过更改变量i
的名称,以防发生任何冲突,但它仍返回相同的错误。我还尝试了不使用.push()
方法的代码段。
答案 0 :(得分:2)
这里的问题显然是循环。尽管sites
文件中JSON对象中的main.json
数组仅包含两个条目,但您的循环进行了四次迭代。这意味着,JavaScript解释器(请记住在运行时对其进行解释)会在第三个循环中引发错误,在该循环中,它找不到name
数组中第三个元素的任何属性sites
没有第三个元素(即JSON对象)。
解决方案1:
您可以通过更改length
循环的条件,将循环的迭代限制为sites
数组的for
:
let main = []
let openJSON = fs.readFileSync('./main.json', 'utf-8');
let parseJSON = JSON.parse(openJSON);
for(let i = 0; i < parseJSON.sites.length; i++){
main.push(parseJSON.sites[i]["name"]);
}
解决方案2:
如果迭代次数需要保持固定的长度(例如像您的示例中的4
),则可以使用try-catch
块来捕获错误。请查看下面的示例。
let main = []
let openJSON = fs.readFileSync('./main.json', 'utf-8');
let parseJSON = JSON.parse(openJSON);
for(let i = 0; i <= 4; i++){
try {
main.push(parseJSON.sites[i]["name"]);
} catch (TypeError) {
// handle TypeError
console.log(`No property 'name' found for entry at index ${i}`)
}
}
解决方案3:
在try-catch
解决方案(即解决方案2)有效的同时,对于Julian所述的给定场景来说,可能太多了。因此,我提供了以下解决方案,用于检查索引sites
处的i
数组是否具有条目或为undefined
。请注意,此解决方案中包含两种可能性。
let main = []
let openJSON = fs.readFileSync('./main.json', 'utf-8');
let parseJSON = JSON.parse(openJSON);
for(let i = 0; i <= 4; i++){
// declare current entry (for readability)
const currEntry = parseJSON.sites[i]
// checking if there is an i-th entry in sites
if (currEntry) {
main.push(currEntry["name"]);
}
// same solution, more compact approach
currEntry ? main.push(currEntry["name"]) : null
}