【问题标题】:How to implement optional chaining / checking nested object properties using VanillaJS or Lodash如何使用 VanillaJS 或 Lodash 实现可选链接/检查嵌套对象属性
【发布时间】:2017-08-02 11:34:33
【问题描述】:
我正在寻找重写以下代码的解决方案:
data && data[name] && data[name].accounts[0] && data[name].accounts[0][user[userName]] && ...
据我所知,有 lodash _.get 方法,但是如何在不失去代码可读性的情况下使用名称、用户名等动态属性?
我也发现了 babel-plugin-transform-optional-chaining,但提到的包的最新版本被命名为 alfa 版本。它似乎不适合大型 PROD 项目。
关于如何编写这种语法的任何其他想法?
谢谢
【问题讨论】:
标签:
javascript
webpack
ecmascript-6
lodash
babeljs
【解决方案1】:
问题中的数据结构是什么样的有点不清楚,尤其是最后一点:user[userName]。假设数据结构如下所示:
let name = 'angelos';
let userName = 'epithemiou'
let data = {
angelos: {
accounts: [
{
epithemiou: 'Hello there'
}
]
}
}
然后使用模板文字和 lodash 的 get 函数,您可以这样做:
let result = _.get(data, `${name}.accounts[0].${userName}`);
【解决方案2】:
就在我的脑海中,一个函数如何接受一个对象和一个作为单独参数传入的路径,然后使用循环返回路径末尾的对象或undefined 如果路径不存在?
function getField(obj, ...path){
if(!obj)
return undefined;
let curr = obj;
for(let i = 0; i < path.length; i++){
curr = curr[path[i]];
if(typeof curr == "undefined" || curr == null)
return undefined;
}
return curr;
}
// our data object
let data = {
henry : {
accounts : [{dude : "Hello World" }]
},
greg : {
accounts : []
}
}
// our search terms
let name = "henry",
username = "dude";
console.log(getField(data, name, "accounts", 0, username)) // Hello World
console.log(getField(data, "greg", "accounts", 0, username)) // Undefined
console.log(getField(data, "shrek", "accounts")) // Undefined
为了使其更具“可读性”,您也许可以将字符串作为路径,然后通过诸如“。”之类的字符对其进行解析/拆分。或 '/',然后使用模板字面量传入动态变量。
function getField(obj, path){
path = path.split(".");
if(!obj)
return undefined;
let curr = obj;
for(let i = 0; i < path.length; i++){
curr = curr[path[i]];
if(typeof curr == "undefined" || curr == null)
return undefined;
}
return curr;
}
// our data object
let data = {
henry : {
accounts : [{dude : "Hello World" }]
},
greg : {
accounts : []
}
}
// our search terms
let name = "henry",
username = "dude";
console.log(getField(data, `${name}.accounts.0.${username}`)) // Hello World