0

I am running into an unexpected behaviour regarding JS objects. Please correct me what I am doing wrong.

<?php // BISMILLAHIRRAHMANIRRAHEEM
?>
<!DOCTYPE html>
<head>
    <title>test</title>
    <script>
        var testobj = {};
        var ret = '{"status":true,"Action":"GetContacts","data":{"0":{"company":"abc","faxnumber":"111"},"1":{"company":"def","faxnumber":"222"},"2":{"company":"ghi","faxnumber":"333"}},"message":""}';
        var retobj = JSON.parse(ret);
        function Process() {
            var list = retobj["data"];
            // Label 1
            testobj = {};
            console.log(testobj);
            // Label 2
            testobj = {};
            console.log(testobj); // Not empty!!
            // Label 3
            //testobj = {};
            //console.log(testobj);
            Object.keys(list).forEach(function(key) {
                testobj[key] = {};
                testobj[key]["Name"] = list[key]["company"];
                testobj[key]["Number"] = list[key]["faxnumber"];
            });
            // Label 4
            console.log("After assigned:");
            console.log(testobj);
        }
    </script>
</head>
<body>
    <a href="javascript:Process();">Click</a>
</body>
</html>

I need to reset an object back to empty. (I read the posts regarding delete on this site). While experimenting other options, I am looking for an explanation as to why testobj is not logged empty to console output? console outputs testobj filled with data that is expected to be filled later in the code. If I comment out the two lines of code under // Label 2, the console output under // Label 1 gives a filled testobj. Likewise if // Label 1, 2, 3 are all uncommented, the console output gives first two testobj as empty and the third one filled with data to be filled later. Somehow the latest assignment of testobj = {}; is getting the object assigned to the about-to-be-assigned data. It happens for the first click/ iteration of Process(); as well when the object is supposed to be empty initially atleast.

Please point me to the right direction. I've tested this on Firefox v75.0 and Chrome v81.0.4044.129

Reading the answers to this post, it makes sense that the console shows the first two objects empty until expanded:

Object {  } // <--- empty

Object {  } // <--- not empty

After assigned:
Object { 0: {…}, 1: {…}, 2: {…} }

... at which point it should show the current state of the object. However, no matter in which order you expand the object nodes in console, the last testobj = {}; before forEach loop is the one that shows the current/ updated value of the object. Why is that? Uncommenting all the three labels gives:

Object {  } // <--- empty

Object {  } // <--- empty

Object {  } // <--- not empty

After assigned:
Object { 0: {…}, 1: {…}, 2: {…} }

Also, i in Chrome debugger shows for each object:

Value below was evaluated just now

Update: console.log(JSON.parse(JSON.stringify(testobj))); shows expected output (all objects empty before being assigned) in all the three label cases. I still find it strange that console showed current/ (realtime?) object value only for the last testobj = {}; prior to being assgined the values.

1 Answers1

0

Your code logs two empty objects, underneath label 1 and 2.

Under label 3, you assign properties to the object from label 2, based on the list object, and log that.

Next, when you expand the object from label 2, the browser re-interprets what was logged (it doesn't keep a copy), and looks at the current state of the object, which you modified under label 3. That is what you are looking at.

Wes
  • 950
  • 5
  • 12
  • If I understand correctly, the object logged under label 2 and 4 is the same object? but why is object under label 1 not the same? Aren't they all just the same object declared when `var testobj = {};` ? – speedbooster May 01 '20 at 11:44
  • It's different under 1 because you reassign it to a fresh object -- {} Remember, variable names are just bindings to a specific object. You can change the bindings without changing the object. The console logs the object, and doesn't care about the bindings. – Wes May 01 '20 at 11:55
  • and under 2 the next fresh object {} was assigned, which later got populated with key-value pairs? – speedbooster May 01 '20 at 18:32