2015-05-23 13 views
5

Klonuję tablicę obiektów przy użyciu slice(), ale kiedy przekazuję tę sklonowaną tablicę do innej metody, zawartość tablicy traci swoje referencje i staje się undefined.Coffeescript/Javascript Dlaczego obiekty w sklonowanej tablicy wydają się tracić swoje referencje po przekazaniu do metody?

class Chooser 
    constructor: (@order, @items) -> 
    # do stuff 

    choose: -> 
    console.debug "Choosing", @order.size, "from", @items.slice() 
    @process(@order.size, @items.slice()) 
    # do stuff 

    process: (count, items) -> 
    console.debug "count", count 
    console.debug "items", items 
    console.debug "@items", @items 
    # do recursive stuff that includes an items.shift() 

Pierwszy console.debug daje mi, zgodnie z oczekiwaniami:

Choosing 10 items from [Item, Item] 

gdzie Item i Item są dokładnie to, czego się spodziewałem.

Ale potem następny console.debug linie dają mi

count 10 
items [undefined x 2] 
@items [Item, Item] 

Rozumiem, że @items.slice() tworzy płytkie kopię @items i jako takie obiekty w tablicy są odniesienia do tych samych Item obiektów. Obiekty Item oczywiście nadal istnieją, ponieważ nadal znajdują się w oryginalnej tablicy.

Dlaczego obiekty w sklonowanej macie zdają się tracić swoje referencje raz w metodzie process?

Zobacz ten Working example of the problem converted to Javascript

+2

Proszę wysłać link do przykładu działa na jsfiddle, jsbin, codepen, requirebin czy coś takiego, a potem powiedz nam, co widzisz i czego oczekujesz. Nie ma sensu debugowanie problemu, który według ciebie istnieje, ale inni w komentarzach twierdzą, że tak nie jest. – rsp

+1

Udało mi się odtworzyć błąd, ale nie udało mi się uzyskać strony z skryptem do kawy, aby wygenerować sensowny adres URL. zobacz [to jsfiddle] (http://jsfiddle.net/k0quf8v2/) jednak, który jest konwertowany na javascript ze skryptu kawowego. Powtarza błąd. –

+0

@DaveSag: Proponuję skopiować odpowiedni kod z fiddle ** na ** pytanie, ponieważ kod nie ma bitu usuwającego wpisy z tablicy, co powoduje problem z konsolą później. Gwarantuje to, że pytania będą nadal przydatne dla ludzi w przyszłości, ponieważ zewnętrzne linki gniją, a SO ma być zasadniczo samowystarczalny. –

Odpowiedz

2

Zobacz tę odpowiedź na to, co dzieje się w kodzie:

https://stackoverflow.com/a/24176638/635411

Jak widać krojenie działa poprawnie:

var MyClass = (function() { 
 
    
 
    function MyClass(items) { 
 
    this.items = items; 
 
    } 
 
    
 
    MyClass.prototype.fn1 = function() { 
 
    console.log(this.items); 
 
    this.fn2(this.items.slice()); 
 
    }; 
 
    
 
    MyClass.prototype.fn2 = function(items){ 
 
    console.log(items); 
 
    }; 
 
    
 
    return MyClass; 
 
})(); 
 

 
new MyClass([{id:1, name:'a'}, {id:2, name:'b'}]).fn1();

To, co widzisz, to przesuwanie tablicy przed jej rozwinięciem w konsoli. Jeśli rzeczywiście stringify obiekt widać, że został pomyślnie przeszedł w.

var MyClass = (function() { 
 
    
 
    function MyClass(items) { 
 
    this.items = items; 
 
    } 
 
    
 
    MyClass.prototype.fn1 = function() { 
 
    console.log(this.items); 
 
    this.fn2(this.items.slice()); 
 
    }; 
 
    
 
    MyClass.prototype.fn2 = function(items){ 
 
    console.log(items); 
 
    console.log(JSON.stringify(items, null, 2)); 
 
    items.shift(); 
 
    items.shift(); 
 
    }; 
 
    
 
    return MyClass; 
 
})(); 
 

 
new MyClass([{id:1, name:'a'}, {id:2, name:'b'}]).fn1();

Powiązane problemy