2016-03-10 25 views
9

Sono abbastanza confuso dal comportamento di map().perché una mappa js su un array modifica l'array originale?

Ho un array di oggetti simili:

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

e sto passando questa matrice a una funzione che deve restituire la stessa matrice, ma con tutti i prodotti resi liberi:

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

la funzione è:

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

che restituisce il seguente array:

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

Così ho riscritto la mia funzione di essere:

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

che restituisce l'array come previsto.

MA! E questo è il momento in cui mi perdo la testa, in entrambi i casi il mio array di prodotti originali viene modificato.

La documentazione sulla mappa() dice che non dovrebbe (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).

Ho anche cercato di creare un clone del mio schieramento trasformare la mia funzione come questa

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

Ma ho ancora ottenere lo stesso risultato (che inizia a farmi impazzire).

Sarei molto grato a chiunque possa spiegarmi cosa sto sbagliando!

Grazie

risposta

26

Non stai modificando l'array originale. Stai modificando gli oggetti nella matrice. Se si vuole evitare mutando gli oggetti nel vostro array, è possibile utilizzare Object.assign per creare un nuovo oggetto con le proprietà del originali più eventuali modifiche necessarie:

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

Ciao. Cosa significa "=>" nel codice sopra? –

+1

@HarshaKanchina Questa è la sintassi della funzione freccia grossa aggiunta in ES6. [Qui] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Arrow_functions) contiene alcune informazioni su MDN. – SimpleJ

+0

Javascript finge di essere un linguaggio funzionale, ma proprio come la parola chiave della classe, questo è confuso, non intuitivo e spreca un sacco di tempo. 'Non stai modificando la tua matrice originale. Stai modificando gli oggetti nell'array - anche se questa risposta è corretta è illogico perché nel mondo reale non puoi cambiare parti di qualcosa e farlo rimanere uguale. – Cobolt

8

di approfondire la risposta di SimpleJ - se si dovesse == = i due array, si troverà che non sarebbero uguali (non lo stesso indirizzo in memoria) confermando che l'array mappato è in realtà una nuova matrice. Il problema è che stai restituendo un nuovo array, che è pieno di riferimenti agli oggetti SAME nell'array originale (non restituisce nuovi letterali dell'oggetto, ma restituisce riferimenti allo stesso oggetto). Quindi è necessario creare nuovi oggetti che sono copie dei vecchi oggetti, ovvero, l'esempio Object.assign fornito da SimpleJ.