【问题标题】:How to clone an array and push new value in a chain? [duplicate]如何克隆数组并在链中推送新值? [复制]
【发布时间】:2019-07-26 14:49:47
【问题描述】:

如果我克隆一个数组并像这样推送一个值:

var arr1 = ["foo", "bar"];
var arr2 = [...arr1];
arr2.push("moo");

console.log(arr2); //["foo", "bar", "moo"]

它的行为符合我的预期。但是,如果我像这样链接 push 方法:

var arr1 = ["foo", "bar"];
var arr2 = [...arr1].push("moo");

console.log(arr2); //3 WTF?

我没想到。为什么像第二个示例一样链接 .push() 会返回数字 3 而不是值数组?

【问题讨论】:

  • Push 不会返回它正在推送的数组。 Consider the API on MDN。它返回“调用该方法的对象的新长度属性。”。

标签: javascript arrays ecmascript-6 chaining


【解决方案1】:

如果您绝对想强制执行链接,您可以在数组原型上创建自己的函数。 (不过你应该明白its implication。)

我建议不要使用相同的方法名,所以如果你想走这条路,请自己命名。

这是一个例子:

Array.prototype.add = function(elem) {
    this.push(elem)
    return this
}

const myArray = [].add("foo").add("bar")

console.log(myArray) // logs: [ 'foo', 'bar' ]

【讨论】:

  • 感谢@k0pernicus。链接并不重要,我根本不明白为什么我面前的代码的行为与我的预期不同。
  • 赞成,但信息丰富。
【解决方案2】:

array.push 返回您存储在arr2 变量中的数组的新长度。

您需要以下内容:

var arr1 = ["foo", "bar"];
var arr2 = arr1.concat("moo");
console.log(arr2); 

【讨论】:

  • 谢谢你漫长的一天。
  • 或者直接做var arr2 = [...arr1, "moo"];
  • 嗯有很多方法...@str
  • 传播效率低。
  • 伙计们冷静下来。 @str 我认为@Kobe 的意思是当我已经使用concat 创建新数组时,我的解决方案中不需要传播,因为 concat 不会改变旧数组。 @Kobe您对性能的看法是正确的,但在实际情况下,只要您不编写任何库的关键内部部分,就没有人关心。专注于完成工作,然后再进行大量优化。
【解决方案3】:

正如 mehulmpt 所说,Array.prototype.push() 在推送后返回数组的新长度。但是,使用concat 非常慢。相反,spread 对第一个数组进行切片,并将 push 新值放在单独的一行中:

const arr1 = ["foo", "bar"];
const arr2 = arr1.slice();
arr2.push("moo");

console.log(arr1, arr2)

JSPerf here

编辑:完全忘记了切片。切片比散布快,改用它。

【讨论】:

  • 这很有趣@Kobe,但我想知道 concat() 在处理大规模或多维数组时如何与 spread 方法叠加?
  • @slynagh 我认为它的表现会和这里一样糟糕。最好不惜一切代价避免使用 concat。
  • 传播和传播推送真的很接近,当我运行测试时传播有时更快
  • @WilliamLohan 的传播对我来说始终慢 10% ±3%。确保在运行测试时保持在同一选项卡上,否则结果将不准确。
  • @Kobe concat 在 Edge 上的速度是 Chrome 上的两倍,并且胜过其他方法(这些方法真的很慢)。只是表明我们总是受客户性能的摆布,但也揭穿了永远不要使用 concat 的声明。 :)
猜你喜欢
  • 2012-02-24
  • 2013-09-17
  • 2011-05-11
  • 2016-06-09
  • 2018-12-02
  • 2013-11-14
  • 2019-01-09
  • 2013-08-04
  • 2022-01-13
相关资源
最近更新 更多