Mutability, and pass-by-reference, “new” object, what am I having left out?

I started questioning what I know, or thought that I know, after this question:

Array.fill differs from literal 2D definition on assignment

A JavaScript question, defining an array with predefined length and filling it with values, and then changing one of the values within the second dimension.

Mutability, in this applied case, the first new Array(9) will be my object, containing an empty array([]), with a predefined length of 9. And the first following .fill() will be the called mutable method, making the referenced object([]) into whatever wanted to be filled([…, …, …, …]), retaining the length. In this case, if I try this on a single dimension array, everything will be alright, I’ll be referencing the main object itself, and update the values of it accordingly with it’s keys.

If I take this into the second dimension, I guess this is the part I mainly don’t get about, I’m now instead filling the initial 9-length empty array ([]) with a new single 9-length empty array filled with 9 zeros, for each index filled until last, but it appears not?

Instead, new reference seems to be not considered, or counted as a new object, but more like just a reference. Just the same as this:

var arr1 = new Array(9).fill(0);
var arr2 = new Array(9).fill(arr1);

So instead, I’m filling nine references to the initial, first dimension. So whether I update 3rd, or 4th index for it doesn’t matter, as they all point to the same reference, and update the arr1 reference’s value at specified index.

What is it that I’m missing out here that causes references to be passed instead of a new objects as I thought be?


Thanks to the quick hint in the comments by @Jörg W Mittag, I figured out what I was skipping. I’m calling the new Array(…) into the fill method, like a variable, in any case. What’s different about this ‘variable’ is that, unlike one like a string, or integer, which are correspondingly their values for their own types, for this case, an object’s value is being it’s reference. Simplifying the idea, I figured that out thanks to this pass-by-value visual explanatory reference:

Cat A = new Cat();

void doStuff(Cat B) {
    // use B in some way

In this code, A’s reference is passed into the doStuff function(Similiar to the fill method I was using initially), and then it becomes B inside it’s scope, however, still referencing to the same initial object, A, due to how objects work, and reference back outside the scope of the changes. As mentioned by the link above, they become merely two different remote controllers for the same object.

I applied the same logic, and tried to make sure, of how something similiar would work in the original place I was working on, and here they are:

     * initiate a 9 length array on-the-fly, 
     * fill all the values equal to 0, 
     * send the newly created object into doStuff1 on-the-fly, 
     * log the return of it.
     * console prints out with changed value(Let's say we're not sure at this point the reference carries on).

    function doStuff1(b){
        b[3] = 1;
        return b;

    console.log(doStuff1(new Array(9).fill(0)));

     * initiate a 9 length array, on a variable named 'a',
     * fill all the values equal to 0,
     * send the newly created object into doStuff2,
     * log the variable 'a'.
     * console prints out with changed value('a' variable held the reference into the function, 
     * and carried back it's process outside the scope, proven).
    var a = new Array(9).fill(0);

    function doStuff2(b){
        b[3] = 1;


Objects pass by their references, or copy their references as how type variables(such as int, byte) pass by, or copy their values. As long as their reference stays, they will be mutable, for a variable’s passing into a function, it will be immutable, and only a copy of their value will be given into the function scope, making further internal changes stay within the scope, unless the outer scope variable is directly referred.

    var a = "hello";

    function doStuff(b){
        //no change to a, since b was a copy-value
        b = "hi";
        //direct reference to the original variable, outer scope value changed
        a = "welcome";  
        //b wasn't present until this function was called, and will be dismissed after
    //outer scope var which was changed through doStuff by direct reference

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *