Search code examples
javascriptecmascript-6getes6-proxy

Can I wrap an object in Proxy and trap and use get trap to prevent "TypeError: Cannot read property 'b' of undefined"?


In Javascript, If I try to do this:

var obj = {};
obj.z.c.f.d = 'foo';

`TypeError: Cannot read property 'c' of undefined`

    at repl:1:7
    at ContextifyScript.Script.runInThisContext (vm.js:50:33)
    at REPLServer.defaultEval (repl.js:240:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:442:10)
    at emitOne (events.js:121:20)
    at REPLServer.emit (events.js:211:7)
    at REPLServer.Interface._onLine (readline.js:282:10)
    at REPLServer.Interface._line (readline.js:631:8)

I don't want this error to be thrown.

Just create z.c.f and add d value inside there.

We have a legacy code.

Now I want to wrap this obj in a proxy and be able to trap its methods.

If property is undefined, create one object there, if a non-object value; overwrite it.

I implemented this method and I can simply use this method in Proxy's trap, maybe:

// setByString is not in Object.prototype. Only in my testObject
testObject.setByString('f.o.o', 1999); 
// this adds an f object and an o object inside, then an o value with 1999 to testObject. Merges deeply.

Here my testObject is expected to only have numbers, undefined, strings, objects.

The point is I can't do it with proxies.

They don't seem to have what I need.

Anyway is there a way to do it, if not possible with Proxies?


Solution

  • with proxies you can do exactly what you are looking for:

    var handler = {
        get: function(target, name){
            if(!(name in target))
                target[name] = new Proxy({}, handler);;
            return target[name];
        }
    };
    
    var p = new Proxy({}, handler);
    

    Now, give it a try with:

    p.a.b.c = 45;//no TypeError here !!!
    

    Is it what you expected ?