Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why if I set an object to a new variable it saves initial value of the variable?

Tags:

javascript

I found some strange behaviour of JavaScript with passing variables as a parameter to function, here is the snippet:

var notWorks = {
    aa: "string",
}

function why() {
    var thisWorks = notWorks;
    $.get("/echo/json").then(function() {
        printVal(notWorks);
        printVal(thisWorks);
    });
    notWorks = {};
}

function printVal(val) {
    console.log(val);
}
why();

The output is:

Object {  }
Object { aa: "string" }

With variable notWorks everything is clear - function in then() is called when the variable is already cleared. But why if I set this object to a new variable it saves initial value of the variable? Object is passing to fuction by link, doesn't it?

Fiddle with example: https://jsfiddle.net/cev8m79y/

like image 422
Shide93 Avatar asked Dec 05 '16 14:12

Shide93


2 Answers

With variable notWorks everything is clear - function in then() is called when the variable is already cleared.

Yes.

But why if I set this object to a new variable it saves initial value of the variable? Object is passing to fuction by link, doesn't it?

This line:

var thisWorks = notWorks;

copies the reference to the object from notWorks to thisWorks. There is no ongoing connection between the variables at that point, they just both refer to the same object.

Then you start the get, and set notWorks to refer to a new, blank object. thisWorks still refers to the previous object. So when the get completes later and you log both of them, you see that thisWorks still points to the original object and notWorks still points to the new, blank object.

Let's throw some ASCII-Art at it (okay, technically it's Unicode-Art):

We start with this:

notWorks: Ref11232−−−+
                     |
                     |
                     |
                     |
                     |  +−−−−−−−−−−−−−−+
                     |  |   (object)   |
                     |  +−−−−−−−−−−−−−−+
                     +−>| aa: "string" |
                        +−−−−−−−−−−−−−−+

(The "Ref11232" is just a placeholder for the value of the object reference. We never actually see the value of an object reference, but you can think of it as a number that tells the JavaScript engine where the object is in memory.)

Then in why, you create a new variable, thisWorks, via var thisWorks:

notWorks: Ref11232−−−+
                     |
                     |
                     |
                     |
                     |  +−−−−−−−−−−−−−−+
                     +−>|   (object)   |
                        +−−−−−−−−−−−−−−+
                        | aa: "string" |
                        +−−−−−−−−−−−−−−+
thisWorks: undefined

And you set it to the same value as notWorks via thisWorks = notWorks:

notWorks: Ref11232−−−+
                     |
                     |
                     |
                     |
                     |  +−−−−−−−−−−−−−−+
                     +−>|   (object)   |
                     |  +−−−−−−−−−−−−−−+
                     |  | aa: "string" |
                     |  +−−−−−−−−−−−−−−+
                     |
thisWorks: Ref11232−−+

Now they both point to the same object.

Then you start get, which has no effect on those variables or objects at all.

Then you give notWorks a new value:

notWorks: Ref84325−−−+
                     |  +−−−−−−−−−−−−−−+
                     +−>|   (object)   |
                        +−−−−−−−−−−−−−−+
                        |              |
                        +−−−−−−−−−−−−−−+

                        +−−−−−−−−−−−−−−+
                     +−>|   (object)   |
                     |  +−−−−−−−−−−−−−−+
                     |  | aa: "string" |
                     |  +−−−−−−−−−−−−−−+
                     |
thisWorks: Ref11232−−+

Then you wait for get to complete, and print them out.

like image 80
T.J. Crowder Avatar answered Sep 27 '22 19:09

T.J. Crowder


When you do

notWorks = {}

You are creating a new object and assigning it to notWorks but thisWorks is still the reference to the previous object that is why the outputs are different

like image 38
bugwheels94 Avatar answered Sep 27 '22 20:09

bugwheels94