【问题标题】:Why is js object not empty in console.log before being assigned?为什么在分配之前,console.log中的js对象不为空?
【发布时间】:2020-05-01 11:23:33
【问题描述】:

我遇到了关于 JS 对象的意外行为。请纠正我做错了什么。

<?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>

我需要将一个对象重置为空。 (我在这个网站上阅读了关于deleteposts)。 在尝试其他选项时,我正在寻找关于为什么 testobj 没有在控制台输出中记录为空的解释?控制台输出 testobj 填充的数据预计稍后将在代码中填充。 如果我注释掉// Label 2 下的两行代码,// Label 1 下的控制台输出会给出一个填充的testobj。同样,如果 // Label 1, 2, 3 都未注释,控制台输出将前两个 testobj 显示为空,第三个填充了稍后要填充的数据。 不知何故,testobj = {}; 的最新分配正在将对象分配给即将分配的数据。 它发生在Process(); 的第一次点击/迭代中,当对象最初应该是空的时。

请指点我正确的方向。我已经在 Firefox v75.0 和 Chrome v81.0.4044.129 上对此进行了测试

阅读this post 的答案,控制台将前两个对象显示为空直到展开是有道理的:

Object {  } // <--- empty

Object {  } // <--- not empty

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

...此时它应该显示对象的当前状态。 但是,无论您在控制台中以何种顺序展开对象节点,forEach 之前的 last forEach 循环都是显示对象当前/更新值的循环。这是为什么? 取消注释所有三个标签给出:

Object {  } // <--- empty

Object {  } // <--- empty

Object {  } // <--- not empty

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

此外,Chrome 调试器中的 i 显示每个对象:

刚刚评估了下面的值

更新:console.log(JSON.parse(JSON.stringify(testobj))); 在所有三种标签情况下显示预期输出(所有对象在分配之前为空)。我仍然觉得奇怪的是控制台在分配值之前仅显示 last testobj = {}; 的当前/(实时?)对象值。

【问题讨论】:

    标签: javascript javascript-objects


    【解决方案1】:

    您的代码在标签 1 和 2 下记录了两个空对象。

    在标签 3 下,您根据列表对象从标签 2 为对象分配属性,并记录下来。

    接下来,当您从标签 2 展开对象时,浏览器会重新解释记录的内容(它不保留副本),并查看对象的 当前状态,其中您在标签 3 下进行了修改。这就是您正在查看的内容。

    【讨论】:

    • 如果我理解正确,标签 2 和 4 下记录的对象是同一个对象吗?但是为什么标签1下的对象不一样?它们不都是var testobj = {}; 时声明的同一个对象吗?
    • 在 1 下是不同的,因为您将它重新分配给一个新对象 -- {} 请记住,变量名只是对特定对象的绑定。您可以在不更改对象的情况下更改绑定。控制台记录对象,并不关心绑定。
    • 并且在 2 之下分配了下一个新对象 {},后来填充了键值对?
    猜你喜欢
    • 2020-08-08
    • 2021-03-05
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 2013-03-22
    • 2022-11-10
    • 2021-06-25
    • 2021-05-16
    相关资源
    最近更新 更多