Javascript 更新对象的更好方法';在可变深度处的s值

Javascript 更新对象的更好方法';在可变深度处的s值,javascript,object,local-storage,Javascript,Object,Local Storage,我正在开发一些软件,使用处理程序在localStorage中读取/写入信息。您可以在此处找到一个工作示例: 我的问题是下面的代码段(侧重于switch语句): 我不是唯一一个使用此代码库的人,我正在努力让其他人能够轻松地更新任何可以放置在localStorage中的值。现在,您可以使用类似于local.set('item.subitem.proeprty','value')的方法更新值。尽管上面的代码可以这样做,但它很难看,而且无法缩放 如何改进此方法(1)自动更新嵌套在任何深度的属性,而不是编

我正在开发一些软件,使用处理程序在
localStorage
中读取/写入信息。您可以在此处找到一个工作示例:

我的问题是下面的代码段(侧重于switch语句):

我不是唯一一个使用此代码库的人,我正在努力让其他人能够轻松地更新任何可以放置在
localStorage
中的值。现在,您可以使用类似于
local.set('item.subitem.proeprty','value')的方法更新值。
尽管上面的代码可以这样做,但它很难看,而且无法缩放

如何改进此方法(1)自动更新嵌套在任何深度的属性,而不是编写无限长的switch语句,以及(2)在更新值后不将父对象与
[object object]
放在一起


这个问题与我使用的
localStorage
无关。我最初在CodeReview中发布了这个问题,它需要一个有效的上下文示例。他们立即结束了这个问题,因为我的部分问题是,一旦您开始处理更新嵌套超过六个对象的值,我提供的代码就无法工作。虽然我可以无限期地继续我的switch语句,但这正是我试图避免的

通过提供的三个示例,您将看到在一个位置设置值并不会删除其他位置的值:

 local.set('user.session.timeout', false);
 local.set('user.name', {first:'john', last:'doe', mi:'c'});
 local.set('user.PIN', 8675309);

所有这些值虽然在不同的时间设置,但只会更新或创建一个值,它们不会清除其他地方预先存在的值。

您可以尝试类似的方法,如果路径不存在,则该值为空:

函数retreiveValueFromObject(路径,对象){
var pathList=path.split(“.”);
var currentValue=对象;
var=false;
对于(变量i=0;ilog(someObject)您需要的是一点递归,我刚刚实现了update方法

let localStorageHandler = function() {
    let b = window.localStorage,
         _t = this;
    _t.get = function(a) {
        try {
            return JSON.parse(b.getItem(a))
        } catch (c) {
            return b.getItem(a)
        }
    };

    function descendAndUpdate(obj, path, value) {
        let current = path[0],
            remainingPath = path.slice(1);
        // found and update
        if (obj.hasOwnProperty(current) && remainingPath.length === 0) {
            obj[current] = value;
        // found but still not there
        } else if (obj.hasOwnProperty(current)) {
            return descendAndUpdate(obj[current], remainingPath, value);
        }
        // if you want do add new properties use:
        // obj[current] = value;
        // in the else clause
        else {
            throw('can not update unknown property');
        }
    }

    _t.set = function(path, value) { // Update a single value or object
        if (~path.indexOf(".")) {
            let o = path.split(".")[0],
                p = this.get(o),
                q = path.split(".").slice(1);
            descendAndUpdate(p, q, value);
            console.log(p);
            b.setItem(o, JSON.stringify(p));
            return p;
        } else {
           b.setItem(path, JSON.stringify(value));
            return this.get(path);
        }
    };
    _t.remove = function(a) { // removes a single object from localstorage
        let c = !1;
        a = "number" === typeof a ? this.key(a) : a;
        a in b && (c = !0, b.removeItem(a));
        return c
    };
};
let local = new localStorageHandler();


// Create user and session info if it doesn't exist
let blankUser = new Object({
    alias: '',
    dob: '',
    PIN: '',
    level: 0,
    name: {
        first: '',
        last: '',
        mi:'',
    },
    session: {
        token: '',
        timeout: true,
        lastChange: Date.now()
    }
});

local.remove('user');

// Loads user data into localstorage
if (!local.get('user')) {
     local.set('user', blankUser);
}

local.set('user.session.timeout', false);
local.set('user.name', {first:'john', last:'doe', mi:'c'});
local.set('user.PIN', 8675309);

// new property
// local.set('user.sunshine', { 'like': 'always' });

console.log(local.get('user'));

我的一个朋友总是喜欢堆栈而不是递归,这是第二种选择。无论如何,我同意这里的许多评论。您已经知道您的域模型。除非您有很好的理由使用这种方法,否则请花更多的时间序列化和取消序列化数据库中的对象。我的印象是,您将能够以更自然的方式处理数据,因为数据库中更新字段的方面将被抽象掉。

至于我,最小优化如下:

    if (~path.indexOf(".")) {
        let o = path.split(".")[0],
            p = this.get(o),
            q = path.split(".").slice(1),
            dist = p;
            q.forEach(function(item, index) {
                if (index < q.length - 1) {
                    dist = dist[item];
                } else {
                    dist[item] = value;
                }
            });
        b.setItem(o, JSON.stringify(p));
        return p;
    } else {
if(~path.indexOf(“.”){
设o=path.split(“.”[0],
p=这个。得到(o),
q=路径分割(“.”)切片(1),
dist=p;
q、 forEach(功能(项目、索引){
如果(索引
更改部分:

  • 创建dist变量
  • 硬编码开关被foreach取代

  • 我现在正在做一个类似的项目,我正在做的是将数据存储在我称之为WordMatrix()的东西中,也许你可以在你的解决方案中使用类似的东西

    我的项目是一个WIP,但下一步就是添加对localStorage的支持。该项目本身是一个数据库编辑器,可以使用key=>value stores。您可以在此处查看它的原型:()


    一旦我实现了localStorage特性,我将更新这篇文章。

    您的主题让我想起了最近的一篇文章

    为了增强我提供的功能,我建议您使用以下功能:

    //获取嵌套元素的函数:
    函数obj_get_path(obj,path){
    返回路径.split('..).reduce((acu,val)=>acu[val]| |“未找到”,obj);
    }
    //函数设置嵌套元素:
    函数对象设置路径(对象、路径、值){
    var结果=obj;
    var path=path.split('.');
    var len=路径长度;
    对于(变量i=0;i
    如何:

    函数解析(str){
    var arr=str.split('.');
    返回函数(obj){
    返回arr.reduce((o,i)=>o[i],obj);
    }
    }
    设foo={
    a:{
    b:{
    c:{
    酒吧:0
    }
    }
    }
    }
    设c=parse('a.b.c')(foo);
    控制台日志(c.bar);
    c['bar']=1;
    
    console.log(foo);
    lodash有一个名为set的函数,这可能是您的after->我应该提到的是项目的所有者
        if (~path.indexOf(".")) {
            let o = path.split(".")[0],
                p = this.get(o),
                q = path.split(".").slice(1),
                dist = p;
                q.forEach(function(item, index) {
                    if (index < q.length - 1) {
                        dist = dist[item];
                    } else {
                        dist[item] = value;
                    }
                });
            b.setItem(o, JSON.stringify(p));
            return p;
        } else {