使用变量访问JSON对象属性报undefined但直接访问属性正常
问题描述
我尝试通过变量读取JSON对象的属性,使用变量访问时会报错,但直接写属性名访问却可以正常运行。
JSON结构如下:
{ "homebrews": { "books": { "title": "text." }, "cards": { "template": { "id": 0, "name": "myName" } } } }
调用的函数代码:
createHomebrew('card');
函数定义:
function createHomebrew(type) { var homebrew; $.getJSON('/data-files/templateHomebrew.json', function(json) { var id = type + 's'; // 拼接得到cards homebrew = json.homebrews[id].template // 此处报错json.homebrews[id] is undefined }); }
直接写属性名访问时可以正常输出结果:
console.log(json.homebrews.cards.template); // 正常输出 Object { id: 0, name: "myName"}

请问出现该问题的原因是什么,该如何解决?
原因及解决方案
出现该问题主要有两种常见原因,对应解决方案如下:
原因1:拼接后的属性名不符合预期,或JSON实际返回结构与预期不一致
你虽然理论上拼接type + 's'应该得到cards,但实际运行中可能因为传参异常(比如type值带空格、大小写错误、拼写错误),或者服务端实际返回的JSON结构和你预设的不一致,导致拼接出来的id不是json.homebrews下存在的属性。
解决方案:
先加日志确认实际运行值,同时增加属性存在性校验避免报错:
function createHomebrew(type) { var homebrew; $.getJSON('/data-files/templateHomebrew.json', function(json) { var id = type + 's'; // 打印确认实际值 console.log('拼接得到的属性名:', id); console.log('homebrews下所有可用属性:', Object.keys(json.homebrews)); // 先判断属性是否存在再访问,兼容低版本浏览器可去掉可选链改用&&逐层判断 if (json.homebrews?.[id]?.template) { homebrew = json.homebrews[id].template; // 后续处理homebrew的逻辑要写在这里 } else { console.error(`homebrews下不存在${id}属性,或该属性下没有template字段`); } }); }
原因2:异步逻辑处理错误
$.getJSON是异步请求,回调函数会在网络请求完成后才执行,如果你在回调函数外访问homebrew变量,此时请求还没返回,赋值语句还没执行,homebrew自然是undefined,很多人会误以为是回调内的赋值语句出错。
解决方案:
所有依赖homebrew的逻辑都要写在回调函数内部,或者改用Promise、async/await的方式处理异步逻辑:
// 用async/await改造示例 async function createHomebrew(type) { const json = await $.getJSON('/data-files/templateHomebrew.json'); const id = type + 's'; const homebrew = json.homebrews[id]?.template; // 后续处理逻辑 return homebrew; }
内容的提问来源于stack exchange,提问作者Artemis
相关产品推荐
相关产品推荐

