2016-03-10 41 views
9

Jestem dość zdezorientowany przez zachowanie mapy().dlaczego mapa js w tablicy modyfikuje oryginalną tablicę?

Mam tablicę obiektów tak:

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

i jestem przechodzącej tej tablicy do funkcji, która powinna zwrócić tę samą tablicę, ale ze wszystkimi produktami wykonany darmo:

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

funkcja:

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

które zwraca następującą tablicę:

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

Więc przepisał mój funkcję być:

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

która zwraca tablicę zgodnie z przeznaczeniem.

ALE! I właśnie w tym momencie tracę rozum, w obu przypadkach moja oryginalna tablica produktów jest modyfikowana.

Dokumentacja wokół mapy() mówi, że nie powinna (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).

Próbowałem nawet stworzyć klona mojej tablicy zwrotnym moją funkcję jak ten

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

ale wciąż uzyskać taki sam wynik (który zaczyna prowadzić mnie do szału).

Byłbym bardzo wdzięczny każdemu, kto może mi wyjaśnić, co robię źle!

Dziękujemy

Odpowiedz

26

Nie modyfikujesz oryginalnej tablicy. Modyfikujesz obiekty w tablicy. Jeśli chcesz uniknąć mutacji obiektów w swojej tablicy, można użyć Object.assign aby utworzyć nowy obiekt z właściwościami oryginału powiększona o zmianach trzeba:

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

Witam. Co oznacza "=>" w powyższym kodzie? –

+1

@HarshaKanchina To jest składnia funkcji tłuszczu tłuszczu dodana w ES6. [Tutaj] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Arrow_functions) to niektóre informacje na ten temat na MDN. – SimpleJ

+0

Javascript udaje język funkcyjny, ale podobnie jak słowo kluczowe klasy, jest to mylące, nieintuicyjne i marnuje dużo czasu. 'Nie modyfikujesz oryginalnej tablicy. Modyfikujesz obiekty w tablicy "- chociaż ta odpowiedź jest poprawna, jest nielogiczna, ponieważ w realnym świecie nie możesz zmienić części czegoś i sprawić, by pozostały takie same. – Cobolt

8

Aby rozwinąć na odpowiedź SimpleJ - jeśli miałeś == = dwie tablice, okaże się, że nie będą one równe (nie ten sam adres w pamięci), potwierdzając, że odwzorowana tablica jest w rzeczywistości nową tablicą. Problem polega na tym, że zwracasz nową tablicę, która jest pełna odwołań do obiektów SAME w oryginalnej tablicy (nie zwraca ona nowych literałów obiektów, ale zwraca referencje do tego samego obiektu). Musisz więc tworzyć nowe obiekty, które są kopiami starych obiektów - tj. W/Object.assign przykład podany przez SimpleJ.