0

Giving the following example:

const a = {
  b: {
    c: null
  }
};

let d = ["b", "c"];

let reference = a;

d.forEach(key => (reference = reference[key]));

reference = "fe";

console.log("With a reference to the object deep key.");
console.log(a);

a["b"]["c"] = "fe";
console.log("Directly setting it, what I want.");
console.log(a);

Would it be possible to change the value of c with a reference to it? This is the closest I am but it obviously stores the null value on it.

Zeswen
  • 261
  • 4
  • 12
  • `let ref = a.b; ref.c = 'fe';` is the best you can do. `ref = ...` never modifies an existing object. – deceze Mar 04 '20 at 13:01
  • Does this answer your question? [Is JavaScript a pass-by-reference or pass-by-value language?](https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language) – VLAZ Mar 04 '20 at 13:03
  • Not directly. You can keep a reference one layer higher on `a['b']` for example, which is an Object and has a reference. – Andrew Radulescu Mar 04 '20 at 13:18

2 Answers2

1

You need to pop the last key from d and use it on reference at the end.

let d = ["b", "c"],
    last = d.pop(),
    reference = a;

path.forEach(key => reference = reference[key] || {});

reference[last] = "fe";

You can use reduce to get the object's reference in the accumulator and update the last key with the provided value

function updatePath(original, path, value) {
  const last = path.pop();
  path.reduce((acc, key) => acc[key] || {}, original)[last] = value;
  return original
}

const eg1 = {
  b: {
    c: null
  }
}

console.log(
  updatePath(eg1, ['b', 'c'], 'fe')
)

const eg2 = {
  1: {
    2: {
      3: 'initial'
    }
  }
}

console.log(
  updatePath(eg2, ['1', '2', '3'], 'updatedValue')
)
adiga
  • 34,372
  • 9
  • 61
  • 83
  • 1
    The more generic concept of a configurable setter/getter is called *functional lenses* or just *lenses* (plural, or *lens* singular). [Here is an article on them](https://medium.com/javascript-scene/lenses-b85976cb0534). [Ramda has an implementation](https://ramdajs.com/docs/#lens). [Lodash also has one](https://lodash.com/docs/4.17.15#set) but doesn't call it a lens. – VLAZ Mar 04 '20 at 13:31
0

You can only change values "by reference" for arrays and objects. But for objects and arrays, yes you can!

You can check this post that explains well the primitive values vs reference values.

Ricardo Rocha
  • 14,612
  • 20
  • 74
  • 130