JavaScript如何在对象内部嵌套插入新的属性或子对象?
错误原因说明
你之前的写法报错的核心原因是要赋值的嵌套父对象不存在:ob['user2'] 初始值是 undefined,对 undefined 执行属性读写操作必然抛出异常。你不想用的一次性赋值整个子对象的写法,问题是会直接覆盖子对象的原有属性,不符合只追加不修改老数据的要求。
通用解决方案(仅追加不覆盖原有内容)
基础兼容写法(适配所有浏览器)
只需要加一行父对象初始化逻辑,父对象不存在就初始化为空对象,已经存在就复用原有值,不会覆盖老数据:
var ob = { user1: {name: 'chris'} }; // 初始化父属性,已存在则复用原有值,不存在才设为空对象 ob['user2'] = ob['user2'] || {}; // 再给子属性赋值 ob['user2']['name'] = 'Luana';
简洁写法(ES6+ 现代浏览器可用)
用空值合并运算符写更短,效果完全一致:
ob.user2 ??= {}; ob.user2.name = 'Luana';
对应你的实际场景实现
1. gentleman 对象需求实现
var gentleman = {}; var test = 0; onclick = () => { test += 1; // 初始化父属性,不覆盖原有内容 gentleman.names ??= {}; gentleman.names[test] = `Im gentleman ${test}`; console.log(gentleman); }
执行后完全符合你要的嵌套结构,每次点击只会新增属性,不会覆盖之前已有的编号属性。
2. 钢琴应用场景实现
首先修正你的初始对象语法(对象键值对用冒号,不是等号):
var songs_ = { music1: 'name', music2: 'name', notes_: {} };
琴键按下的逻辑,顺便实现了「音频已存在就不重复创建」的判断:
// keyName 是当前按下的琴键名,比如 'C'、'C_'、'D' function onKeyPress(keyName, urlNote) { // 仅当该琴键音频不存在时才创建,已有实例直接复用不覆盖 if (!songs_.notes_[keyName]) { songs_.notes_[keyName] = new Audio(urlNote); } // 后续播放逻辑直接调用已有实例即可 songs_.notes_[keyName].currentTime = 0; songs_.notes_[keyName].play(); }
这个写法不会修改/覆盖 notes_ 里的已有属性,只会新增不存在的琴键对应音频实例,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Chris Answood
相关产品推荐
相关产品推荐

