Shide93
Shide93

Reputation: 123

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

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/

Upvotes: 8

Views: 130

Answers (3)

T.J. Crowder
T.J. Crowder

Reputation: 1074168

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.

Upvotes: 10

Shai
Shai

Reputation: 3872

It's because you don't really affect the object when the line notWorks = {} is executed, you only remove the reference to it from notWorks. thisWorks still points to the same object in memory.

Upvotes: 0

bugwheels94
bugwheels94

Reputation: 31920

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

Upvotes: 4

Related Questions