【问题标题】:Doesn't the ES6 spread operator flatten an array?ES6 扩展运算符不会展平数组吗?
【发布时间】:2017-01-10 10:16:55
【问题描述】:

没有具体反应,所以希望可以问,但我认为扩展运算符会使数组变平?

因此,使用以下对 args 求和的 sum 函数,您可以使用 .apply 传入值:

function sum() {
    return arguments.reduce((total, number) => total + number, 0);
}

var values = [2, 4, 8, 12, 16];

console.log(sum.apply(null, values));

我认为您可以只添加函数并使用扩展运算符来展平数组,以便可以使用调用。 (我知道你不会在这种情况下使用 call ,但我只是感到惊讶,因为我认为传播使数组变平:

function sum() {
    return [...arguments].reduce((total, number) => total + number, 0);
}

var values = [2, 4, 8, 12, 16];

console.log(sum.call(null, values));

这将返回字符串02,4,8,12,16

【问题讨论】:

    标签: javascript arrays ecmascript-6


    【解决方案1】:

    发生这种情况是因为arguments 类似于数组。数组变为字符串。

    作为call documentation says

    虽然此函数的语法与 apply() 的语法几乎相同,但根本区别在于 call() 接受参数列表,而 apply() 接受单个参数数组。

    这应该可以按预期工作:

    sum(...values);
    sum.call(null, ...values);
    sum.apply(null, values);
    

    顺便说一句,argumentscall 在 ES6 中是不受欢迎的。

    【讨论】:

    • 谢谢你。您能否简要解释一下为什么在 .call 上传播这些值?如果它已经是一个平面阵列,为什么要在那里传播?感谢您在 ES6 中使用参数和调用使用 - 这是为什么呢? (非常感谢帮助)
    • 我已经更新了答案。这是callapply 之间的主要区别。前者接受 args 列表(可以从数组传播)。后者接受一个 args 数组。
    • 是的,明白了 - 感谢 estus,只是对为什么在 ES6 中不使用调用和参数感兴趣?
    • arguments 方便地替换为 ...args 其余参数。并且 callnull 上下文被替换为扩展参数。
    • 另外,arguments 不能用于箭头函数。
    【解决方案2】:

    arguments 是一个类似数组的结构,因此在将数组作为参数传递时,该结构就像一个嵌套数组。因此,应用扩展运算符会生成格式为[[2, 4, 8, 12, 16]](即[...[[2, 4, 8, 12, 16]]])的数组,reduce 方法应用0 + [2, 4, 8, 12, 16] 并生成"02,4,8,12,16"

    要使其工作,您需要使用 Function#apply 将数组值作为参数传递或获取第一个参数。

    function sum() {
      return [...arguments].reduce((total, number) => total + number, 0);
    }
    
    var values = [2, 4, 8, 12, 16];
    
    console.log(sum.apply(null, values));

    function sum() {
      return [...arguments][0].reduce((total, number) => total + number, 0);
    }
    
    var values = [2, 4, 8, 12, 16];
    
    console.log(sum.call(null, values));

    参考:What is the difference between call and apply?

    【讨论】:

    • 谢谢Pranav,但是为什么数字数组变成了字符串?使用 .call 实例,为什么参数仍然不是数字数组?
    • 另外,这会返回 NaN
    • @LeMoi :您需要使用apply 将元素数组作为参数传递......console.log(sum.apply(null, values));
    • @LeMoi:检查 sn-p
    • 是的,我知道这是一个不好的例子,只是想了解为什么扩展运算符没有展平数组,所以如果我使用 .call 在 sum 函数中记录参数,则参数是包含所有数字的嵌套数组。
    猜你喜欢
    • 2016-02-26
    • 1970-01-01
    • 2019-09-14
    • 1970-01-01
    • 2016-06-12
    相关资源
    最近更新 更多