这是什么假话?为什么要重复数据删除?以及为什么console.log()包含在foreach前面时的答案?

时间:2018-06-26 04:07:31

标签: javascript

Q1-为什么即使在forEach之前,该消息也随对象一起打印?
Q2-为什么要对新对象进行重复数据删除 问题3:什么触发了伪造,允许添加{}?

var test = [{id:1,name:'s1'},{id:2,name:'s2'},{id:2,name:'s2'},{id:1,name:'s1'},{id:4,name:'s4'}];

    var test1 = {};
    //Q1
    console.log(test1);

    test.forEach(function(item){
     //Q2 and Q3
     var o = test1[item.name] = test1[item.name] || {};
     o.id = item.id;
    });

    <!--Output 
    {}
    ​
    s1: Object { id: 1 }
    ​
    s2: Object { id: 2 }
    ​
    s4: Object { id: 4 }
    ​
    __proto__: Object { … }
     --!>

2 个答案:

答案 0 :(得分:2)

控制台很棘手。它不会说谎,它只是存储对该对象的引用。它并不是在记录对象时“照像”它,而是实际上反映了对象本身。如果要在单击时更新它,它也会在控制台中更新该引用。如果您发出警报,则将获得[object Object]而不是文本。您可以使用console.log(JSON.stringify(test1))来打印内容,就像在代码中读取对象时一样。

关于重复数据删除,这很简单,但是有点逻辑难题。例如,在一次迭代中,它将看到test1['s1']并将其分配给's1'。下次它在另一个s1上运行时,实际上是在引用与之前相同的属性test1['s1'],然后再次将其重新分配给's1'。

我将再次仔细研究问题3,但是在这里一次在StackOverflow上问一个明确的问题是一个好主意。 ;)

-

编辑:好吧,说实话,我不确定您如何在日志中获取这些值,因为即使我运行相同的脚本,也不会得到相同的结果。检查我在codepen上的代码以查看我的脚本是否按预期工作!

答案 1 :(得分:2)

Q1。如评论所述,主要浏览器现在记录对象的可检查树,而不是使用对象的toString方法将对象转换为字符串。该树基于对对象的引用,并可能在展开树时而不是在记录对象时显示当前的属性值。

Q2。 forEach循环使用test1数组中项目的item.name值设置test的属性。如果在name条目中重复test个值,则在test1中仅更新一个属性名称。因此,重复数据删除-对象无法存储具有相同名称的单独属性。

Q3。将test1属性初始化为空对象仅在test1中为item.name中保留的属性名称首次创建属性时发生。随后,如果再次遇到相同的item.name值,它将从test1检索预先存在的属性,因为

test1[item.name] || {};

现在求值为现有的test1对象属性。 (如果||运算符的左操作数为非false,则返回左运算符值作为运算结果。)

这可能会留下o变量-它是对存储在test1中的对象的引用的副本。更新其id属性将更新与test1中保存的对象相同的对象。如果test具有多个相同名称但值不同的id条目,则该名称的test1属性将保留{{1}中最后一个重复条目的id }。