0

I have an object of functions & I need to add a new, single method called log(it prints the method's name) to each function within the Object dynamically at runtime.

For instance, let's say this is my dynamic object of functions:

let actions = { 
  theBoringFunction() { 
    return 'function 1'
  },

  anotherBoringFunction() {
    return 'function 2'
  },

  theMostBoringFunction() {
    return 'function 3'
  },
}

I can add a new function to the methods individually like so:

actions.anotherBoringFunction.log = function () {  
  return console.log(this.name)
}

actions.anotherBoringFunction.log() // logs anotherBoringFunction

It works like a charm, but I have many functions within the actions object & I need to add log() to all of them.

I have tried looping through the object & adding the method like so:

// won't work key is typeof String :(
for (let key in actions) { 
  key.log = function () { 
    return console.log(this.name)
  }
}

Obviously, it didn't work cause key is a type of string so it cannot add a method to it. How could I accomplish what I'm looking for? I have been trying with proxies, but no luck so far either.

Edit Number 1:

I have added a reproducible, example here.

let actions = { 
  theBoringFunction() { 
    return 'function 1'
  },

  anotherBoringFunction() {
    return 'function 2'
  },

  theMostBoringFunction() {
    return 'function 3'
  },
}

// won't work key is typeof String :(
/* for (let key in actions) { 
  key.log = function () { 
    return console.log(this.name)
  }
} */

actions.anotherBoringFunction.log = function () {  
  return console.log(this.name)
}

actions.anotherBoringFunction.log() // logs anotherBoringFunction
Dominique Fortin
  • 2,212
  • 15
  • 20
Manuel Abascal
  • 5,616
  • 5
  • 35
  • 68
  • 1
    `actions[key].log =`, `key` is the property name (a string) – ASDFGerte Sep 09 '20 at 16:37
  • `for..in` loops through the keys - you want `for..of` for the values. – Robin Zigmond Sep 09 '20 at 16:39
  • @RobinZigmond `for ... of` works on iterables, you'd have to use e.g. `for (let fn of Object.values(actions)) fn.log = /*...*/`, which indeed would also work. – ASDFGerte Sep 09 '20 at 16:41
  • 1
    I am not fully sure i understand your intend. You could create some abomination that behaves similarly in your case, but generally, [arrow functions and regular functions are not freely exchangeable](https://stackoverflow.com/questions/34361379/are-arrow-functions-and-functions-equivalent-exchangeable). If a regular function's behavior of `this` (which you do seem to use) is your intention, then changing to an arrow function may be counter-productive. If you mean doing the assignments, then `Object.values(actions).forEach(v => v.log = /*...*/);`, but I'd prefer abovementioned `for ... of` then – ASDFGerte Sep 09 '20 at 16:52
  • It kind of depends on your intentions - what you are currently doing, is creating a new `log` function for every property, while the function itself uses `this` to log the related name. Therefore, you could use the same `log` function for all of them (just one function), but i don't know, what this code's intention and use-cases are. – ASDFGerte Sep 09 '20 at 16:55
  • @ASDFGerte thanks, you are of course correct, I always seem to forget this – Robin Zigmond Sep 09 '20 at 17:33

1 Answers1

1
for (let key in actions) { 
  actions[key].log = function () { 
    return console.log(this.name)
  }
} 
Dolly
  • 2,213
  • 16
  • 38