Search code examples
javascriptrecursionlogicjavascript-objects

How does editing a Javascript Object in a recursive function successfully edit the real object?


I wrote a recursive function which takes a '.' separated object path, and a payload. It then modifies the matching key of the object with the payload.

The function is as follows:

function objWalker(object, path, payload) {
    let pathArr = path.split(".");
    if (pathArr.length > 1) {
        objWalker(object[pathArr[0]], //new object
          path.slice(path.indexOf(".") + 1), //new shortened path
          payload);
    } else {
        object[path] = payload;
    }
}


const testObject = {
    a: {
        b: {
            c: {
                d: "e"
            }
        }
    },
    ab: "cd",
    abc: {
        def: {
            ghi: ["j", "k"]
        }
    }
};
objWalker(testObject, "abc.def.ghi", { new: "element" })
console.log(testObject)

This function works fine. When I looked into deeper why this works, one doubt I had is: For every recursive call to function objectWalker, the first parameter I am passing is object[pathArr[0]]. When this function is called again as a result, with object[pathArr[0]], does this not create a new variable tied to the new function call?

What I mean to say is, what connection does the object variable in the current recursive call has with the object variable of the previous recursive call, so that when the function exits the current call after changing the object variable, it is reflected in the final result?

And when we are hitting the else condition after 'n' recursive calls finally, according to my understanding, the current object in the function has no connection to the original object. Then when we finally make the change, i.e. object[path] = payload, and the function exits all the calls, how does the change reflect in the original object? How does that work?


Solution

  • All objects are addresses towards the function so unlike C an object is never copied. It is still considered pass by value.

    So the binding you get points to an object. If you change the binding by altering what the variable is supposed to be it never changes the object but just re-references the variable.

    When you update a property on an object you are no longer altering a variable. You are changing the property of an object. You are mutating and all references / properties that has that object will get the updated version.