JavaScript嵌套对象赋值报错,求原因及修改方案
问题分析与修改方案
错误原因
你遇到的报错核心是直接嵌套访问对象属性时,上层的对象节点未提前初始化。
第一次循环处理第一个.looper元素时,myObj[attr1](即myObj['1'])是undefined,此时直接尝试访问myObj['1']['1'],相当于读取undefined的属性,自然会抛出Cannot read properties of undefined的错误。
修改方案
有两种常用解决方式,任选其一即可:
方式一:逐层检查并初始化对象(兼容性好)
在给最内层属性赋值前,先确保每一层的对象都存在,不存在则创建空对象:
function initLoop() { //this loads the initial frames into the object $('.looper').each(function(i, e){ var attr1 = $(this).attr('attr1'); var attr2 = $(this).attr('attr2'); var attr3 = $(this).attr('attr3'); var contents = $(this).html(); // 初始化attr1对应的层级 if (!myObj[attr1]) { myObj[attr1] = {}; } // 初始化attr2对应的层级 if (!myObj[attr1][attr2]) { myObj[attr1][attr2] = {}; } // 安全赋值 myObj[attr1][attr2][attr3] = contents; }); }
方式二:使用ES2020+语法简化代码(更简洁)
如果运行环境支持ES2020及以上,可以用??=(逻辑空赋值)简化初始化逻辑:
function initLoop() { //this loads the initial frames into the object $('.looper').each(function(i, e){ var attr1 = $(this).attr('attr1'); var attr2 = $(this).attr('attr2'); var attr3 = $(this).attr('attr3'); var contents = $(this).html(); // 仅当上层对象不存在时,创建空对象 myObj[attr1] ??= {}; myObj[attr1][attr2] ??= {}; myObj[attr1][attr2][attr3] = contents; }); }
额外提示
如果希望把属性值从字符串转为数字作为对象键,可以把属性获取代码改成:
var attr1 = Number($(this).attr('attr1')); var attr2 = Number($(this).attr('attr2')); var attr3 = Number($(this).attr('attr3'));
不过对象的键本质上都是字符串,这一步不做也不影响功能,根据实际需求选择即可。
内容的提问来源于stack exchange,提问作者John Sly
相关产品推荐
相关产品推荐

