sebpiq
sebpiq

Reputation: 7812

Weird behaviour when copying array with slice

I am using Backbone.js, and in an overriden collection's add method I'm trying to copy an array with slice, the following way :

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

But copy doesn't seem to work, here's what my (chromium) log shows :

COPIED [] [child]

Any idea what could cause this ?

EDIT :

Here's a jsfiddle that reproduces the problem: http://jsfiddle.net/hYDbw/5/

Upvotes: 0

Views: 101

Answers (4)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

This isn't a case of the copy failing; it's a case of the copied array going out of scope before console.log actually outputs it, because console.log works asynchronously on some browsers (such as Chrome), and arrays are passed around by reference.

For example:

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

foo();

Under some conditions, you'll see [1,2,3] output rather than the [] that you'd expect.

In your scenario, I'm not entirely sure what's going on, but I suspect modelsBefore has been re-used and emptied for the next invocation of code at that scope.

If you stringify early, though, you can get around it:

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

foo();

Stringification is a synchronous process, so you're guaranteed to see [] there.

Upvotes: 1

PeterK
PeterK

Reputation: 61

The Collection.models in Backbone is not an Array, it is an Object. Do not expect .slice() to work correctly with it. Look for another implementation that can do what you are expecting from .slice().

Upvotes: 0

Asken
Asken

Reputation: 8081

Slice requires start parameter

Upvotes: 1

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

The first argument to slice is not optional:

array.slice(begin[, end])

So:

this.models.slice(0);

Upvotes: 3

Related Questions