根据给定的字符串,修改一个多层嵌套对象对应的属性值

发布于 2022-09-07 21:01:24 字数 783 浏览 21 评论 0

题目描述

我在localStorage里面储存用户信息userInfo,要封装一个修改userInfo的方法

相关代码

// userInfof里面有很多信息
var userInfo= {
    id:'123',
    name:'Jim',
    info:{
        address:{
            home:'地王大厦',
            work:{
               workDays:'腾讯大厦',
               weekend:'阿里巴巴大厦',
               festival:'百度大厦',
            },
        },
        money:{
            balance:0,// 余额
            redPacket:0,// 红包
            integral:0,// 积分            
        }
    }
}
// 比如修改localStorage.userInfo.info.address.work.workDays为京东大厦,则
editFn('userInfo.info.address.work.workDays','京东大厦');

// 比如修改localStorage.userInfo.info.money.balance为888,则
editFn('userInfo.info.money.balance','888');

你期待的结果是什么?

这个editFn方法改怎么写?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

野心澎湃 2022-09-14 21:01:24
function editFn(path, value, obj) {
    const arr = path.split('.')
    const len = arr.length - 1
    arr.reduce((cur, key, index) => {
            if (!(cur[key]))
                throw `${key} 不存在!`
            if (index === len) {
                cur[key] = value
            }
            return cur[key]
        }, obj)
}

editFn('info.address.work.workDays','京东大厦', userInfo);

这里要求 userInfo 已经是解析后的一个 object,因此 path 部分不能再以 userInfo 开头。

再一次这个没有处理数组的情形,需要留意。

内心旳酸楚 2022-09-14 21:01:24

如果你非要用这种方法来修改的话……,首先要明确一个,就是LocalStorage存储的是字符串
所以我假设你的LocalStorage里面存的对象是JSON.stringify()转出的json

function RewriteLS(LSkey,fn){
    //Write接收一个回调函数作为参数,回调函数的参数为要修改的obj
    if(!localStorage[LSkey]){
        localStorage[LSkey] = JSON.stringify({});
    }
    let Obj = JSON.parse(localStorage[LSkey]);//这里应当先判断isJSON,我就省略了,懒得写
    Obj = fn(Obj)||Obj; //这里可以随你return,直接用引用修改的话就不用return了
    console.log(Obj);
    localStorage[LSkey] = JSON.stringify(Obj)
}
function editFn(path,value){
    let pathArr = path.split(".");
    RewriteLS(pathArr.splice(0,1),(obj)=>{
        try{
            eval("obj."+pathArr.join(".")+"=value");
        }catch(e){
            //中间的path可能出错。
            throw e;
        }
    })
}

我直接使用了eval来处理赋值,如果你想的话,循环或者递归来resolve路径也是可以的。
但是你所说的传递一个字符串路径的方式我十分不推荐。

你可以看到我单独封装了一个RewriteLS函数,使用该函数

RewriteLS("userInfo",obj=>{
    //在这里对obj的属性进行处理
});

来处理的话会更加灵活,也更安全。

吝吻 2022-09-14 21:01:24
if (!(cur[key]))
                throw `${key} 不存在!`

这里不太合理.如果给一个全新对象赋值嵌套属性的话,直接崩溃.
改造一下:

if (!(cur[key])) {  
    try {  
        Object.defineProperty(cur, key, {value: {}, writable: true, configurable: true, enumerable: true});  
  } catch (e) {  
        console.error(e);  
  }  
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文