【问题标题】:Is it okay to change the value of an array inside the Array.every, Array.some e.t.c可以更改 Array.every、Array.some 等内部数组的值吗
【发布时间】:2015-01-12 17:04:36
【问题描述】:

以下代码有效。但它是在函数式编程风格的方法中修改数组值的正确方法吗?

a = [1, 2, 3];
a.every(function(val,index, arr) {
 if (val === 2) {
    arr[index] += 1;
 }
});

【问题讨论】:

  • 不是真的,你可能想要map 而不是every
  • 为什么不呢?您可以修改someevery 中的数组值。您也可以删除值,并且方法仍将按预期工作。事实上,这两种方法都旨在支持这种行为。 ecma-international.org/ecma-262/5.1/#sec-15.4.4.17 但是在你的例子中你不应该使用every 你应该使用map
  • 如果你要使用mapfilter 等......你最好避免突变,继续我认为它需要的风格。如果我需要“修改”数组并且没有方法帮助,那么我会使用 reduce 和一个全新的累加器。
  • 对于这个用例来说,使用 for 循环似乎很合法,除非您实际上还需要旧版本的数组。只是说

标签: javascript functional-programming


【解决方案1】:

没有。尽管您的代码有效,但从概念上讲,您应该改用forEach 方法,请参阅here(另外,为了便于阅读,请删除您的 arr 参数并使用 this。)

【讨论】:

  • 这取决于情况(对于这个特定的例子,map 是更惯用的函数),但一般来说,如果你想从你的函数中编辑数组,你可能会更好关闭forEach。另外,forEach 不是 jQuery 方法,所以this 指的是全局对象或在严格模式下未定义。
  • @Qantas94Heavy,你说的很对,this 不能在回调中使用。我将编辑我的答案。但是,我不同意使用 map,因为它的目的是创建一个新数组,这不是 OP 想要的。
【解决方案2】:

但是在函数式编程风格的方法中修改数组值是否正确?

没有。使用函数式编程范例,您不应该修改任何对象(无论您使用什么方法)。更好:

var a = [1, 2, 3];
var b = a.map(function(val) {
  return (val === 2) ? 3 : val;
});

请注意,像您一样使用every 是没有意义的——您对测试所有元素的谓词不感兴趣。当你真的想从你的回调中执行副作用时,你应该使用forEach(这不是很实用,但至少让你的意图很清楚)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多