2015-05-12 11 views
8

Czy istnieje alternatywna metoda dostępna w lokalu, podkreślniku lub innej bibliotece, która prawie zachowuje się w taki sam sposób, z tym wyjątkiem, że zwraca nowy obiekt zamiast mutować pierwszy argument ?.Niezmienna funkcja _.assign (przypisać z klonem) z podkreślenia lodash lub innej biblioteki?

var o = { 'user': 'barney' } 
var result = method(o, { 'age': 40 }, { 'user': 'fred' }) 

// o still { 'user': 'barney' } 
// result is now { 'user': 'fred', 'age': 40 } 
+0

Przepraszamy, podczas wyodrębniania obiektu jako zmiennej lokalnej o, zapomniałem wymienić fragment, który wyodrębniłem. – Chad

+0

Rzeczywistym zamiarem, jak powiedziałem, jest stworzenie nowego obiektu podobnego do o, ale nadpisanego przez kolejne obiekty. To upewnia mnie, że mam wersje o przed i po nadpisaniu. – Chad

Odpowiedz

16

Najczęstszym sposobem w ten sposób wydaje się używać pustego obiektu i przypisać na które, jak:

var result = _.assign({}, l, m, n, o, p); 

To nie jest technicznie niezmienne ale będzie produkować „nowy” obiekt, który nie istnieje przed wywołaniem funkcji.

Pamiętaj, że nawet bardzo sprytna implementacja klona musiałaby robić to samo. Ręczne tworzenie nowego obiektu jest trywialne, więc większość bibliotek nie martwi się o pomocnika w tym przypadku. Najbliższą rzeczą będzie _.create, co ma więcej wspólnego z przypisaniem właściwego prototypu.

2

Wypróbuj immutable-js

var result = Immutable.Map(o).merge({ age: 40, user: 'fred' }).toObject(); 
console.log(result); // { user: 'fred', age: 40 } 
console.log(o); // { user: 'barney' } 
+0

Szukałem '' immutable-js'', ale wydaje się, że ma problemy z działaniem z innymi bibliotekami, takimi jak '' lodash''. Spojrzałem na niezmienną niezmienność, która oferuje kompatybilność wsteczną z tablicami i obiektami, jednak nie jestem pewien, jak zmierzy się z niezmienną-js. – Chad

+0

Czy próbowałeś używać metod 'toJS()' i 'fromJS()'? Te wydają się działać całkiem dobrze dla mnie. –

+0

Po prostu uważam, że są trochę niezgrabne. Myślę, że są one jednak funtional. – Chad

5

Lubię defaults() w przypadkach takich jak ten.

var user = { user: 'barney', age: 36 }; 

_.defaults({ age: 40 }, user); 
// → { user: 'barney', age: 40 } 

user; 
// → { user: 'barney', age: 36 } 

Pierwszy argument jest celem, a user nie jest zmutowany. Lubię używać defaults(), kiedy muszę nadpisywać właściwości, tak jak w przypadku tutaj z age, ale nie chcę niczego zmieniać w oryginale. Ponieważ defaults() doda tylko właściwości, które zostaną przekształcone w undefined. Właściwość age istnieje w literale obiektu, więc jego wartość jest zachowywana.

Podejście assign() działa równie dobrze - defaults() to tylko inny sposób myślenia o tym.

+0

Z dokumentacji dla loka 4.13: "Uwaga: Ta metoda mutuje obiekt." https://lodash.com/docs#defaults –

+0

Tak, ale mutuje pierwszy obiekt, więc jeśli umieścisz "dodatkowe" rzeczy przed "domyślnym" obiektem, to jest to nowy obiekt, który zostaje zmutowany, a nie -istniejący obiekt. Minusem jest to, że musisz umieścić swoje dodatkowe rzeczy przed domyślnym obiektem - który czuje się do tyłu. –

+0

Należy pamiętać, że wartość 'null' pozostanie nienaruszona, ponieważ nie jest' niezdefiniowana'. To samo dotyczy '_.defaultsDeep()'. W większości prawdziwych scenariuszy 'null' powinno zostać nadpisane. Alternatywą jest użycie ['_.mergeWith()'] (https://lodash.com/docs/4.17.4#mergeWith) i obsługa przypadków w razie potrzeby. Dodatkowo nazywanie funkcji dostosowywania pozwala na powtarzanie. –