2015-03-01 22 views
5

Questa è una domanda piuttosto generale. La programmazione in stile funzionale promuove l'idea che un programma riguarda la trasformazione dei dati attraverso le funzioni e che la mutazione dovrebbe essere evitata (tranne forse all'interno di una funzione, vista come unità di base dell'astrazione).JavaScript in stile funzionale: buona pratica per evitare la mutazione degli argomenti?

Ma in questo programma:

function foo (bar) { 
    bar.k1 = "bananas"; 
    return bar; 
} 

var o = { k1: "apples", k2: "oranges"}; 
var p = foo(o); 

variabile o esterna è mutato all'interno foo perché bar è un riferimento o, e, alla fine, o === p (essi riferimento allo stesso oggetto). Ma il paradigma funzionale preferirebbe che p fosse un nuovo dato.

La soluzione più ovvia è quella di clonare l'argomento (e g usando sottolineatura/di _.clone lodash..):

function foo (_bar) { 
    var bar = _.clone(_bar); 
    bar.k1 = "bananas"; 
    return bar; 
} 

Ma mi chiedo se questo è il modo corretto di pensare a questo problema. In una prospettiva FP, considereresti una buona pratica clonare gli oggetti passati come argomenti se saranno mutati? (Sono consapevole che non tutti gli oggetti possono essere clonati facilmente, se non del tutto, ma restiamo fedeli a casi semplici). I tuoi pensieri?

+0

Il mio 2 centesimi è quello di scrivere codice che funzioni con la lingua e non rimanere attaccato alle tecniche di programmazione. La programmazione funzionale va bene e dandy, ma se non hai bisogno di un nuovo oggetto non c'è motivo di restituirne uno, quando puoi semplicemente cambiare l'originale. – adeneo

+0

Ho bisogno di restituire l'oggetto se voglio fare qualcosa del tipo: 'someOtherFunction (foo (o))'. Quello che probabilmente intendi è che non importa se si tratta di un oggetto nuovo o di un riferimento all'oggetto esterno. –

+0

Che sia importante o meno dipende da voi? Hai bisogno che l'oggetto originale sia invariato, altrimenti non c'è motivo di crearne uno nuovo, basta restituire quello passato alla funzione dopo che è stato modificato. – adeneo

risposta

5

Idealmente, la funzione dovrebbe restituire un oggetto nuovo ogni volta che viene chiamato. Ovviamente per motivi di prestazioni non è eccezionale, questo è il motivo per cui esistono persistent data structures. Ci sono alcune librerie per JS; immutable-js è probabilmente il più popolare.

Altrimenti la mutazione dell'oggetto va bene, e in JS è pratica comune, poiché non tutti i progetti beneficerebbero immediatamente di strutture di dati persistenti, oltre al peso della libreria.

Si noti inoltre che in JavaScript tutto viene passato per valore, ma i valori stessi possono contenere riferimenti.