【问题标题】:Can someone explain me why we used curly braces "{}" in this code?有人能解释一下为什么我们在这段代码中使用花括号“{}”吗?
【发布时间】:2019-08-20 04:22:31
【问题描述】:

当我试图检查一个元素在数组中使用了多少次时,我发现了这段代码。它是由另一个用户编写的,我让它工作,但我试图弄清楚他为什么最后使用“{}”。我知道 .reduce() 方法可以获得 initialValue 但我无法理解大括号的使用。

var a = ["a","b","b","c","a","b","d"];  
 
 var map = a.reduce(function(obj, b) { obj[b] = ++obj[b] || 1;    
 return obj;
  }, {});

我认为它们可能是 initialValue 参数,因为它涵盖了结果,但是当我尝试删除大括号时结果不一样。我还检查了 MDN 文档,发现了一些类似的代码,但由于我对 JavaScript 很陌生。

当我们使用大括号时,我得到:

{
  a: 2,
  b: 3,
  c: 1,
  d: 1
}

但是当我移除大括号并运行它时,我得到:

a

我尝试使用括号,结果为:[ a: 2, b: 3, c: 1, d: 1 ],

所以大括号似乎包含了值,但它不应该像往常一样在没有大括号的情况下工作吗?

【问题讨论】:

  • 文档:Array.prototype.reduce() syntaxarr.reduce(callback[, initialValue]) "initialValue : 用作第一次调用回调的第一个参数的值。如果没有提供初始值,将使用数组中的第一个元素。"
  • I know that .reduce() method can get initialValue but I could not understand the use of braces. 好吧,如果是var obj = {},你可以理解它,这是相同的 - 对象文字的符号。所以你的初始值将是一个空对象。
  • "我认为它们可能是 initialValue 参数" - 是的。 “但是当我尝试删除大括号时结果不一样” - 为什么您在更改调用时期望得到相同的结果?
  • 谢谢大家的评论,我不知道{}是一个空对象。所以我很好奇它是否有一些特殊功能(在这种情况下是一个对象)或者只是对内容进行排序。

标签: javascript iterator iteration


【解决方案1】:

accumulator对象。可以说它是初始值,所以当回调函数被执行时,初始值将是一个空对象。

所以在下面的示例中,它最初传递的是一个具有键 e 的对象

var a = ["a", "b", "b", "c", "a", "b", "d"];

var map = a.reduce(function(obj, b) {
  console.log(obj)
  obj[b] = ++obj[b] || 1;
  return obj;
}, {e:'test'});

console.log(map)

【讨论】:

    【解决方案2】:

    大括号{}在javascript中代表一个新的空对象,在你的例子中,它将是reduce方法返回给map变量的对象,我们需要先初始化它然后填充它reduce 回调的核心。

    用作回调第一次调用的第一个参数的值。如果未提供初始值,则将使用数组中的第一个元素。在没有初始值的空数组上调用 reduce() 是错误的。

    initialValue 看看 reduce(),这是一个示例,如果您要提供初始值作为 reduce() 的第二个参数,则结果如下所示:

    let arr = [0, 1, 2, 3, 4];
    
    arr = arr.reduce((accumulator, currentValue, currentIndex, array) => {
      return accumulator + currentValue;
    }, 10);
    
    console.log(arr);

    【讨论】:

    • 谢谢,我明白了。我刚开始学习对象,所以我不知道“{}”是什么意思。所以当我们放 {} 时,它的意思是,获取这些值,处理它们,并将它们作为对象分配给变量,对吧?
    • 当我们执行{} 时,我们使用obj={}; 之类的空对象初始化累加器obj,然后在reduce 的回调中使用进程数据填充此对象。
    • 感谢您的澄清。它真的帮助了我。我刚开始学习对象,所以我期待自己测试这个技巧。谢谢!
    • 不客气,很高兴我能帮上忙,祝编码愉快。 (恭喜,您已获得 VoteUp privilege 如果任何答案对您有帮助,请考虑使用它)。
    【解决方案3】:

    .reduce() 方法中的第二个参数是initialValue,它是一个

    用作回调第一次调用的第一个参数的值。如果没有提供初始值,将使用数组中的第一个元素。


    tl;dr

    这是.reduce() 开头的初始值。这是第一次调用中传递给回调的第一个参数。


    在您的情况下,想法是从数组中构建一个值映射,其中映射中的键是数组中的值,而映射中的值是该值在数组中出现的次数。

    JS 中的地图可以很容易地由一个对象模拟,在您的情况下,该对象已作为文字 {} 传递给 .reduce() 方法。该方法为数组中的每个元素触发回调,将结果对象作为第一个参数,将数组中的当前元素作为第二个参数。但问题在于第一次调用 - 如果数组中没有先前的元素要累积,应该使用什么值作为结果对象?这就是为什么您需要传递一些初始值才能开始的原因。正如 MDN 所述,如果没有传递 initialValue,则使用数组的第一个元素 - 这就是为什么在删除初始值时得到 a 的原因。当您传递 [] 时,您告诉 JS 将数组字面量作为初始值,但在回调中,您将其视为 JS 中允许的对象,因为数组也是对象。当您尝试迭代这些属性或使用JSON.stringify() 对它们进行字符串化时,就会出现问题。但这是另一个故事;)

    【讨论】:

    • 所以我们可以使用 .reduce() 来处理不同的数据类型并得到不同的结果,就像示例中一样。我已经看到了数学运算符的使用,例如将数字数组减少为单个数字等。通过使用这种方法,我可以 .reduce() 一些数据并将其分配给一个对象。感谢您的快速回复!
    【解决方案4】:

    但是当我移除大括号并运行它时,我得到:a

    这是syntax

    arr.reduce(callback[, initialValue]) 
    

    initialValue :用作回调第一次调用的第一个参数的值。 如果没有提供初始值,将使用数组中的第一个元素。"

    因此,如果您使用reduce 而不使用initialValue({}),则数组中的第一项将用作initialValue,即"a"

    所以,它变得类似于:

    var a = ["a", "b", "b", "c", "a", "b", "d"];
    
    var map = a.slice(1).reduce(function(obj, b) {
      obj[b] = ++obj[b] || 1;
      return obj;
    }, "a");
    
    console.log(map)

    在第一次迭代中,

    obj[b] = ++obj[b] || 1;
    

    变成

    "a"["b"] = ++"a"["b"] || 1
    

    这既不会引发异常,也不会更改obj 字符串。 obj还是"a",每次都会返回。

    【讨论】:

    • 我明白了。所以我知道,.reduce() 得到一个 accumulatorValue 并用 currentValue 处理它,但它在“obj[b] = ++obj[b] || 1;”中是如何工作的部分? İnitialValue 是一个空对象。这意味着 reduce 将从一个空对象开始。意思是 {}[b] = ++{}[b] 我猜。但是“b”值是什么,我仍在努力弄清楚。 :)
    【解决方案5】:

    {} 创建新对象,如果你不添加这个,那么将使用数组中的第一个元素。

    您可以看到,当您使用 {} 运行代码时,您会得到一个空对象作为 initialValue 并满足您的要求。

    var a = ["a","b","b","c","a","b","d"];  
     
    var map = a.reduce(function(obj, b) { 
        "use strict";
    
        if (Object.entries(obj).length === 0 && obj.constructor === Object) {
            console.log("InitialValue is defined as object: ", obj);
        }
        obj[b] = ++obj[b] || 1;    
        return obj;
    }, {});
    
    console.log(map);

    而没有{},它会将数组a 的第一个值分配给obj,这意味着现在obj 是一个字符串,当您尝试将其用作对象时,它会引发错误,如下所示代码。

    var a = ["a","b","b","c","a","b","d"];  
     
    var map = a.reduce(function(obj, b) { 
        "use strict";
    
        console.log("InitialValue not defined: ", obj);
        obj[b] = ++obj[b] || 1;    
        return obj;
    });
    
    console.log(map);

    我刚刚添加了"use strict" 来显示这个错误。

    【讨论】:

    • 感谢您的解释。 :) 这对我来说似乎是一个高级的,但我明白你的意思。
    猜你喜欢
    • 2019-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    相关资源
    最近更新 更多