javascriptobject

Add nested properties to non existent properties using dot notation


In javascript, we can add new properties to an object using dot notation

const obj = {}
obj.a = "hello"

console.log(obj) // prints { a: "hello" }

However, with dot notation it is not possible to add a property to a not yet existent object

obj.a.b = "hello" // <-- cannot set properties of undefined (setting 'b')
obj.a = { b: "hello" } // <-- OK

I would like to achieve this behaviour

const obj = {}
obj.a.b = "hello"

console.log(obj) // prints { a: { b: "hello" } }

My Idea

The only thing i could think of which could get close to this, would be using a proxy

const obj = new Proxy({}, {
    set(target, key, receiver) {
        // if a.b could make it here before the error is thrown, i'd handle this
       // btw, this means that "key" should contain [a,b] which is not how this works.
    }
})

obj.a.b = "hello"

The proxy idea cannot work and probably there is absolutely no way of changing JS's native behaviour like I'm asking but maybe I'm missing something instead?


Solution

  • A proxy does work. You need to use the get trap instead of set:

    const obj = new Proxy({}, {
        get(target, key, receiver) {
            if (!(key in target)) return (target[key] = {});
    
            return Reflect.get(target, key);
        },
    });
    
    obj.a.b = "hello";
    
    console.log(obj);