0

I have the following code for adding getters to an object on the fly:

const obj = {};
const uni = { name1: ..., name2: ..., ...};
for(const nm in uni) {
  const u = obj[nm] = {};
  Object.defineProperty(u, 'value', {
    configurable: true,
    enumerable: true,
    get: () => { return uni[nm] },
  });
}

I want getters to return different values, so I want uni[nm] to be understood literary, i.e. the first getter would return uni.name1, the second uni.name2 etc.

How do I do that?

EDIT:

I want to dynamically create an object like this:

{
  name1: { get value() { return uni.name1 }},
  name2: { get value() { return uni.name2 }},
  ...
}
  • 1
    I'm not understanding what your goal is. "I want uni[nm] to be understood literary [...]", could you maybe post some code showing what you'd _like_ to work? – CollinD Feb 09 '23 at 03:16
  • @CollinD - added an edit – user9163823 Feb 09 '23 at 03:21
  • Wouldn't you just change `"value"` to `nm`? – CollinD Feb 09 '23 at 03:21
  • I need exactly what I wrote, an object that has property "name1", which is an object, that has property "value", and that property is a getter that returns uni.name1 (which will be changed dynamically somewhere else in the code) – user9163823 Feb 09 '23 at 03:27
  • @Mulan - the solution offered doesn't have the structure that I need and it only creates a getter for name2 but name1 is a static property. – user9163823 Feb 09 '23 at 03:31
  • @user9163823 your last comment helps me understand you better. i think my updated answer is what you are looking for. – Mulan Feb 09 '23 at 03:36
  • What is the problem? Your code seems to work. – Bergi Feb 09 '23 at 03:57

2 Answers2

1

Don't use for..in. And you pretty much never need Object.defineProperty. That's all stone age JavaScript.

Instead use -

const uni = { name1: "foo", name2: "bar" }

let obj = {}

for(const key of Object.keys(uni)) {
  obj[key] = {
    get value() {
      return uni[key]
    }
  };
}

console.log(obj.name1.value) // "foo"
console.log(obj.name2.value) // "bar"

uni.name1 = "zzz"
console.log(obj.name1.value) // "zzz"

This can be expressed using array.reduce and -

const uni = { name1: "foo", name2: "bar" }

const obj = Object.keys(uni).reduce(
  (o, key) => {
    return {...o, [key]: { get value() { return uni[key] }}} // extend
  },
  {} // initial object
)

console.log(obj.name1.value) // "foo"
console.log(obj.name2.value) // "bar"

uni.name1 = "zzz"
console.log(obj.name1.value) // "zzz"
Mulan
  • 129,518
  • 31
  • 228
  • 259
-2

You can achieve this by using the square bracket notation ([]) to dynamically access properties in the uni object, like this: