简体   繁体   中英

Using only property accessors (dot notation or bracket notation), how do I set undefined nested properties directly?

In a javascript object, is it possible to set property values of undefined nested keys by only using property accessors (eg dot notation or bracket notation)?

Lodash's _.set function (and TJ Crowder's answer) is similar to what I want, but the structure of the code is different, ie, _.set(state, "some.future.key", "baz") .

Are there any libraries that would allow me to directly set the values, ie, state.some.future.key = "baz" ?

Ideally I would want the state to automatically assume the shape of:

state = {
    some: {
        future: {
            key: "baz"
        }
    }
}

You simply create anything that's missing.

 const state = { foo: "bar" }; if (!state.some) { state.some = {}; } if (!state.some.future) { state.some.future = {}; } state.some.future.key = "baz"; console.log(state); 

If it gets to be a lot of inline code, you can provide yourself a function to do it. The answers to this question and this question should get you headed the right way if you want to do that. A simplistic version:

 function setDeep(obj, path, value) { if (typeof path === "string") { path = path.split("."); } const final = path[path.length - 1]; path = path.slice(0, -1); for (const entry of path) { if (!obj[entry]) { obj = obj[entry] = {}; } else { obj = obj[entry]; } } return obj[final] = value; } const state = { foo: "bar" }; setDeep(state, "some.future.key", "baz"); // Or: setDeep(state, ["some", "future", "key"], "baz"); console.log(state); 

...but there are a dozen variations on that.

The simplest way to solve this problem is the Proxy object as shown below:

const state = {
    foo: "bar"
}

var stateHandler = {

    get : function(obj,prop){
         if(obj[prop] == undefined){
            obj[prop]= new Proxy({},stateHandler);
         }
         return obj[prop];
    }
  };

var proxyState = new Proxy(state,stateHandler);

proxyState.koo.loo= 9; 
proxyState.too.noo.too.y = 10899;
console.log(proxyState.koo.loo); //9 
console.log(proxyState.too.noo.too.y); // 10899
console.log(proxyState.foo); // bar 

This will allow you to set property at any nested level.

To do this state.some.future.key = "baz" use this code

state.foo='newbar';
state.some={};
state.some.future={};
state.some.future.key='baz';

and when you print state then you will get

state = {
    foo: "newbar",
    some: {
        future: {
            key: "baz"
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM