2016-03-10 1 views
9

Ich bin ziemlich verwirrt durch das Verhalten von map().Warum ändert eine js-Map in einem Array das ursprüngliche Array?

Ich habe ein Array von Objekten wie folgt aus:

const products = [{ 
    ..., 
    'productType' = 'premium', 
    ... 
}, ...] 

und ich bin vorbei dieses Array an eine Funktion, die die gleiche Array zurückgeben sollte, aber mit allen Produkt frei gemacht:

[{ 
    ..., 
    'productType' = 'free', 
    ... 
}, ...] 

die Funktion ist:

const freeProduct = function(products){ 
    return products.map(x => x.productType = "free") 
} 

welches die folgenden Array zurück:

["free", "free", ...] 

So schrieb ich meine Funktion zu sein:

const freeProduct = function(products){ 
    return products.map(x => {x.productType = "free"; return x}) 
} 

, die das Array zurückgibt, wie beabsichtigt.

ABER! Und das ist der Moment, in dem ich meine Gedanken verliere, in beiden Fällen ist mein ursprüngliches Produkt-Array modifiziert.

Dokumentation rund um Karte() sagt, dass es nicht sollte (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).

Ich habe sogar versucht, einen Klon von meinem Array dreht meine Funktion wie diese

const freeProduct = function(products){ 
    p = products.splice() 
    return p.map(x => {x.productType = "free"; return x}) 
} 

Aber ich bekomme immer noch das gleiche Ergebnis (die mich verrückt zu machen beginnt) zu erstellen.

Ich wäre jedem sehr dankbar, der mir erklären kann, was ich falsch mache!

Vielen Dank

Antwort

26

Sie ändern nicht Ihre ursprüngliche Anordnung. Sie ändern die Objekte im Array. Wenn Sie die Objekte mutiert im Array vermeiden möchten, können Sie Object.assign verwenden, um ein neues Objekt mit dem ursprünglichen Eigenschaften zu erstellen und Änderungen benötigen Sie:

const freeProduct = function(products) { 
    return products.map(x => { 
    return Object.assign({}, x, { 
     productType: "free" 
    }); 
    }); 
}; 
+0

Hallo. Was bedeutet "=>" im obigen Code? –

+1

@HarshaKanchina Das ist die Fettpfeil-Funktionssyntax, die in ES6 hinzugefügt wird. [Hier] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Arrow_functions) gibt einige Infos dazu auf MDN. – SimpleJ

+0

Javascript gibt vor, eine funktionale Sprache zu sein, aber genau wie das Klassen-Schlüsselwort ist dies verwirrend, unintuitiv und verschwendet viel Zeit. 'Sie ändern Ihr ursprüngliches Array nicht. Du modifizierst die Objekte im Array - obwohl diese Antwort korrekt ist, ist es unlogisch, weil du in der realen Welt Teile von etwas nicht ändern kannst und es so bleiben lässt. – Cobolt

8

Um auf SimpleJ Antwort zu erarbeiten - wenn Sie waren in == = die zwei Arrays, Sie würden feststellen, dass sie nicht gleich wären (nicht dieselbe Adresse im Speicher), was bestätigt, dass das abgebildete Array tatsächlich ein neues Array ist. Das Problem ist, dass Sie ein neues Array zurückgeben, das voll von Verweisen auf die SAME-Objekte im ursprünglichen Array ist (es gibt keine neuen Objektliterale zurück, es werden Referenzen auf dasselbe Objekt zurückgegeben). Sie müssen also neue Objekte erstellen, bei denen es sich um Kopien der alten Objekte handelt - dh um das Object.assign-Beispiel, das von SimpleJ angegeben wurde.

Verwandte Themen