perché una mappa js su un array modifica l’array originale?

Sono abbastanza confuso dal comportamento di map ().

Ho una serie di oggetti come questo:

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

e sto passando questo array a una funzione che dovrebbe restituire lo stesso array ma con tutto il prodotto reso gratuito:

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

La funzione è:

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

Che restituisce il seguente array:

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

Quindi ho riscritto la mia funzione per 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 provato a creare un clone del mio array trasformando la mia funzione in questo modo

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

Ma ottengo lo stesso risultato (che inizia a farmi impazzire).

Sarei molto grato a chiunque possa spiegarmi cosa sto sbagliando!

Grazie

Non stai modificando la tua matrice originale. Stai modificando gli oggetti nella matrice. Se si desidera evitare la mutazione degli oggetti nell’array, è ansible utilizzare Object.assign per creare un nuovo object con le proprietà dell’originale più eventuali modifiche necessarie:

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

2018 Modifica:

Nella maggior parte dei browser è ora ansible utilizzare la syntax di diffusione degli oggetti invece di Object.assign per ottenere ciò:

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

Per approfondire la risposta di SimpleJ – se dovessi usare === i due array, scopriresti che non sarebbero uguali (non lo stesso indirizzo in memoria) confermando che l’array mappato è in realtà un nuovo array. Il problema è che stai restituendo un nuovo array, che è pieno di riferimenti agli oggetti SAME nell’array originale (non restituisce nuovi letterali dell’object, ma restituisce riferimenti allo stesso object). Quindi è necessario creare nuovi oggetti che sono copie dei vecchi oggetti, ovvero, l’esempio Object.assign fornito da SimpleJ.