开发者问题收集

JSON 属性不可访问 — “无法读取未定义的属性”

2017-04-21
30526

我尝试使用 Wikipedia API 检索文章标题和文章文本的片段。但是当我尝试访问这些属性时,我收到错误“无法读取未定义的属性”。

这是我的 JSON 响应:

{
    "batchcomplete": "",
    "continue": {
        "gsroffset": 10,
        "continue": "gsroffset||"
    },
    "query": {
        "pages": {
            "13834": {
                "pageid": 13834,
                "ns": 0,
                "title": "\"Hello, World!\" program",
                "index": 6,
                "extract": "<p>A <b>\"Hello, World!\" program</b> is a computer program that outputs or displays \"Hello, World!\" to a user. Being a very simple program in most programming languages, it is often used to illustrate the</p>..."
            },
            "6710844": {
                "pageid": 6710844,
                "ns": 0,
                "title": "Hello",
                "index": 1,
                "extract": "<p><i><b>Hello</b></i> is a salutation or greeting in the English language. It is first attested in writing from 1826.</p>..."
            },
            "1122016": {
                "pageid": 1122016,
                "ns": 0,
                "title": "Hello! (magazine)",
                "index": 7,
                "extract": "<p><i><b>Hello</b></i> (stylised as <i><b>HELLO!</b></i>) is a weekly magazine specialising in celebrity news and human-interest stories, published in the United Kingdom since 1988. It is the United Kingdom</p>..."
            }
        }
    }
}

我尝试了几种不同的代码编写方法。例如,这有效(将页面作为对象记录在控制台中):

console.log(response.query.pages);

但这会返回我上面写的错误(“无法读取未定义的属性”):

console.log(response.query.pages[0].title);

任何有关如何访问属性“title”和“extract”的建议都将不胜感激。谢谢。

3个回答

这是因为 pages 不是数组;它是一个对象,其中的键是 id。因此您需要执行以下操作:

console.log(response.query.pages[1122016].title);

这将起作用。例如,如果您想要“第一”页,则

let pages = response.query.pages;
console.log(pages[Object.keys(pages)[0]].title);

请注意,我不确定 JS 对象中键的顺序是否得到保证。

如果您想遍历页面,请执行

let pages = response.query.pages;
Object.keys(pages).forEach(id => {
    let page = pages[id];
    console.log(page.title, page.foo);
});
Luan Nico
2017-04-21

特殊情况:使用异步调用

各位开发者大家好,

如果您查看此主题是因为您正在使用 React 之类的框架,或者使用开发服务器的其他框架(例如使用 npm start 或类似程序),则当您尝试在数据重新加载之前执行 console.log(response.foo.bar) 之类的操作时,您的开发服务器可能会崩溃。

具体来说,我的开发服务器崩溃了,并显示 无法读取未定义的属性“bar” 类型消息,我当时就想,“这到底是怎么回事!?”。解决方案:将其放入 try/catch 块中:

try { 
    console.log(rate['bar'].rate)
  } catch (error) {
    console.log(error)
  }

为什么?如果您的应用程序具有默认状态(例如,甚至是一个空数组),那么它会尝试在从远程源接收到数据之前 console.log 响应,它将成功记录您的空状态,但如果您尝试在 console.log 或其他任何位置引用您期望从远程源接收的对象的部分,开发服务器将尝试引用初始加载时不存在的内容,并在实际通过 API 或其他方式从远程源接收它时有机会引用它之前崩溃。

希望这对某人有帮助!

Davis Jones
2020-01-17

我不确定您使用哪种语言来解析 JSON(看起来像来自 console.log 的 Javascript?)但问题是 query.pages 是一个字典,而不是一个数组,因此它不能通过索引进行迭代,只能按键进行迭代。

所以你想要类似(伪代码)的东西:

for (key in response.query.keys)
{
    console.log(response.query[key].title);
}
jdunlop
2017-04-21