【问题标题】:Weird behaviour when copying array with slice使用切片复制数组时的奇怪行为
【发布时间】:2012-02-22 11:41:56
【问题描述】:

我正在使用 Backbone.js,并且在覆盖集合的 add 方法中,我尝试使用以下方式复制带有 slice 的数组:

var modelsBefore = this.models.slice(0);
console.log('COPIED', modelsBefore, this.models);

但复制似乎不起作用,这是我的(铬)日志显示的内容:

COPIED [] [child]

知道是什么原因造成的吗?

编辑:

这是一个重现问题的 jsfiddle:http://jsfiddle.net/hYDbw/5/

【问题讨论】:

  • 为什么不将数组存储在另一个变量中?
  • 为什么你没有在slice()中设置任何参数
  • @Sarfraz:这就是他想要做的......
  • @Sarfraz:如果他只是将它分配给另一个变量,那么两者都指向同一个数组。
  • 参数是可选的(即使您的特定实现碰巧以其他方式工作,在其当前版本和配置中,在当前日期和您当前位置)。遵循记录在案的 API,而不是纯粹的机会

标签: javascript backbone.js


【解决方案1】:

sliceis not optional 的第一个参数:

array.slice(begin[, end])

所以:

this.models.slice(0);

【讨论】:

  • @sebpiq:重现问题的测试用例的时间。此外,仅仅因为正确使用 slice 并不能解决您的问题并不意味着您应该决定不正确地使用它。
  • 你要找的词是“问题”
【解决方案2】:

这不是复制失败的情况;这是在console.log 实际上 输出它之前复制的数组超出范围的情况,因为console.log 在某些浏览器(例如Chrome)上异步工作,并且数组通过引用传递。

例如:

function foo() {
   var x = [];
   console.log(x);
   x = [1,2,3];
}

foo();

在某些情况下,you'll see [1,2,3] output rather than the [] that you'd expect

在您的场景中,我完全确定发生了什么,但我怀疑 modelsBefore 已被重新使用并清空以用于该范围内的下一次代码调用。

不过,如果你尽早进行字符串化,你可以绕过它:

function foo() {
   var x = [];
   console.log(JSON.stringify(x));
   x = [1,2,3];
}

foo();

字符串化是一个同步过程,因此您可以保证在那里看到[]

【讨论】:

    【解决方案3】:

    切片需要启动参数

    【讨论】:

    • 你能做一个jsfiddle以便我们测试吗?
    • 事情是......我正在使用backbone.js,但我会尝试。
    • console.log(JSON.stringify(this.models)) 并在 jsfiddle 中使用它?
    • 这里是jsfiddle.net/sebpiq/hYDbw ...我猜这是因为骨干的某种副作用,但我什至不知道这是怎么发生的!!??
    • 这个 jsfiddle 仍然没有透露 this.models 是如何初始化/分配的以及它有什么原型。尝试提出一个最小的测试用例,没有任何多余的代码。你能在没有 Backbone 的情况下重现这个吗?试试这个作为最后的手段:var modelsBefore = Array.prototype.slice.call(this.models, 0);
    【解决方案4】:

    Backbone 中的 Collection.models 不是一个数组,它是一个对象。不要期望 .slice() 可以正常使用它。寻找另一个可以满足您对 .slice() 的期望的实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-27
      • 2019-12-13
      • 1970-01-01
      • 1970-01-01
      • 2016-10-27
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多