鍍金池/ 問答/C++  HTML/ 根據給定的字符串,修改一個多層嵌套對象對應的屬性值

根據給定的字符串,修改一個多層嵌套對象對應的屬性值

題目描述

我在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方法改怎么寫?
回答
編輯回答
陪我終

如果你非要用這種方法來修改的話……,首先要明確一個,就是LocalStorage存儲的是字符串
所以我假設你的LocalStorage里面存的對象是JSON.stringify()轉出的json

function RewriteLS(LSkey,fn){
    //Write接收一個回調函數(shù)作為參數(shù),回調函數(shù)的參數(shù)為要修改的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來處理賦值,如果你想的話,循環(huán)或者遞歸來resolve路徑也是可以的。
但是你所說的傳遞一個字符串路徑的方式我十分不推薦。

你可以看到我單獨封裝了一個RewriteLS函數(shù),使用該函數(shù)

RewriteLS("userInfo",obj=>{
    //在這里對obj的屬性進行處理
});

來處理的話會更加靈活,也更安全。

2018年1月5日 22:19
編輯回答
心癌
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 開頭。

再一次這個沒有處理數(shù)組的情形,需要留意。

2017年7月4日 05:06