Pablo Carson
Pablo Carson

Reputation: 45

Replacing a function deeply nested inside an object in javascript

I have an object containing functions that are nested potentially deeply (could be more levels than this so I need a solution that will work at any depth):

x = {
    a: function() { console.log ("original function 1") }, 
    b: {
        c: {
            d: function() { console.log ("original function 2") }
            }
        }
    }

I want to be able to pass the function's keypath as an argument to another function and replace the original function with a new one:

g = function( functionAddress ) {
    functionAddress = function() { console.log( "replacement function" )}
}

so that after executing:

g("x.b.c.d"); 
x.b.c.d() // replacement function

g("x.a"); 
x(a) // replacement function

I've been able to process the argument using split, shift and reduce so I can access the function at the specified address as in:

keypath = x["b"]["c"]["d"]

but if I try to use newFunc to replace the function at that location, it only replaces the value of keypath, not the function at that address.

Any help would be appreciated. Thanks!

Upvotes: 2

Views: 564

Answers (1)

FZs
FZs

Reputation: 18609

There's no straightforward way to do that. Instead, you have to implement your function to do so.

Here's a more-or-less simple way, using Array#split() and Array#reduce():

const x = {
    a: function() { console.log ("original function 1") }, 
    b: {
        c: {
            d: function() { console.log ("original function 2") }
        }
    }
}

const setDeep = (object, path, value)=>{
  const pathArray=path.split('.')
  pathArray.slice(0,-1).reduce(Reflect.get,object)[pathArray[pathArray.length-1]]=value
}

setDeep(x, 'b.c.d', function(){console.log('replacement function')}); 

x.b.c.d() //replacement function

Upvotes: 1

Related Questions