如何仅书写一次长对象属性,实现未定义时赋默认值并可直接操作
最佳解决方案(ES2021+ 环境)
直接使用逻辑或赋值运算符 ||= 即可实现仅写一次属性路径,同时完成默认值初始化和别名引用:
// 仅出现一次完整属性路径,自动初始化不存在的属性,同时返回实例绑定到变量 const items = store.user[userId].order[orderId].items ||= new Set(); if (items.has('apples')) items.add('oranges');
原理:||= 运算符会先判断左侧属性是否为虚值(undefined/null等),如果是则将右侧的默认值赋值给左侧属性,整个表达式最终返回赋值后的属性值,直接绑定到items变量作为别名,后续操作items会直接作用于原对象的属性。
兼容旧ES版本方案
如果环境不支持||=运算符,可以用三元表达式一次完成判断、赋值、取值:
// 先取最后一级父对象,避免重复写深层路径 const order = store.user[userId].order[orderId]; const items = order.items ? order.items : (order.items = new Set()); if (items.has('apples')) items.add('oranges');
通用深层嵌套初始化方案
如果中间层级(如user[userId]/order[orderId])也可能不存在,可以封装通用工具函数,路径仅需定义一次:
/** * 深层获取对象属性,不存在则自动初始化层级和默认值 * @param {object} obj 根对象 * @param {Array} path 属性路径数组 * @param {*} defaultValue 叶子节点默认值 * @returns 叶子节点值的引用 */ function getOrDefault(obj, path, defaultValue) { return path.reduce((curr, key, idx) => { if (curr[key] === undefined) { curr[key] = idx === path.length - 1 ? defaultValue : {}; } return curr[key]; }, obj); } // 调用时仅需要传入一次路径 const items = getOrDefault(store, ['user', userId, 'order', orderId, 'items'], new Set()); if (items.has('apples')) items.add('oranges');
该方案适合循环批量处理大量深层属性的场景,不需要重复书写嵌套属性链,所有层级不存在时都会自动初始化。
内容的提问来源于stack exchange,提问作者Malvineous
相关产品推荐
相关产品推荐

