Protože objekty v Javascriptu jsou odkazy hodnot, nemůžeš prostě jen kopie pomocí =
. Ale žádné starosti, zde jsou 3 způsoby, jak můžete klonovat objekt 👍
# Objekty jsou Referenční Typy
Vaše první otázka by mohla být, proč nemůžu použít =
. Uvidíme, co se stane, když to uděláme:
const obj = { one: 1, two: 2 };const obj2 = obj;console.log( obj, // {one: 1, two: 2}; obj2, // {one: 1, two: 2};);
zatím se zdá, že oba objekty vydávají stejnou věc. Takže žádný problém, že jo., Ale uvidíme, co se stane, když upravíme náš druhý objekt:
const obj2.three = 3;console.log(obj2);// {one: 1, two: 2, three: 3}; <-- ✅console.log(obj);// {one: 1, two: 2, three: 3}; <-- 😱
WTH?! Změnil jsem obj2
ale proč bylobj
také ovlivněn. To proto, že objekty jsou referenční typy. Takže když používáte =
, zkopíroval ukazatel do paměťového prostoru, který zabírá. Referenční typy nedrží hodnoty, jsou ukazatelem hodnoty v paměti.
Pokud se o tom chcete dozvědět více, podívejte se na Gordonovy Hodinky Zhu a kódový kurz. Je zdarma se přihlásit a sledovat video „srovnání s objekty“., Dává to super úžasné vysvětlení.
# 1. Použití Spread
pomocí spreadu klonuje váš objekt. Všimněte si, že to bude mělká kopie. Od tohoto příspěvku je operátor šíření pro klonování objektů ve fázi 4. Takže to ještě není oficiálně ve specifikacích. Takže pokud byste měli použít toto, budete muset sestavit s Babel (nebo něco podobného).
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = { ...food };console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# 2. Použití Objektu.přiřaďte
alternativně, Object.assign
je v oficiálním vydání a také vytvoří mělkou kopii objektu.,
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = Object.assign({}, food);console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
Poznámka: prázdný {}
jako první argument, to zajistí, že nechcete změnit původní objekt 👍
# 3. Použití JSON
tento konečný způsob vám poskytne hlubokou kopii. Teď se zmíním, že je to rychlý a špinavý způsob hlubokého klonování objektu. Lodash lodash
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = JSON.parse(JSON.stringify(food));console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# Lodash DeepClone vs JSON
zde je komentář od komunity. Ano, Bylo to pro můj předchozí příspěvek, jak hluboce klonovat pole ., Myšlenka se však stále vztahuje na objekty.
Alfredo Salzillo: chtěl bych, abyste si všimli, že mezi deepClone a JSON existují určité rozdíly.stringify / parse.
- JSON.stringify / parse pracuje pouze s číslem a řetězcem a objektem doslovně bez vlastností funkce nebo symbolu.
- deepClone práce se všemi typy, funkce a Symbol jsou kopírovány odkazem.
zde je příklad:
@OlegVaraksin: metoda JSON má problémy s kruhovými závislostmi. Pořadí vlastností v klonovaném objektu se navíc může lišit.,
# Mělký Klon vs Hluboká Klon
Když jsem použil šíření ...
kopírovat objekt, jsem pouze vytvoření mělké kopie. Pokud je pole vnořené nebo vícerozměrné, nebude fungovat. Zde je náš příklad budeme používat:
const nestedObject = { flag: '🇨🇦', country: { city: 'vancouver', },};
# Mělké Kopie
řekněme, klon našeho objektu pomocí šířit:
const shallowClone = { ...nestedObject };// Changed our cloned objectshallowClone.flag = '🇹🇼';shallowClone.country.city = 'taipei';
Tak jsme změnili náš klonovaný objekt tím, že mění město. Podívejme se na výstup.
console.log(shallowClone);// {country: '🇹🇼', {city: 'taipei'}}console.log(nestedObject);// {country: '🇨🇦', {city: 'taipei'}} <-- 😱
mělká kopie znamená, že první úroveň je zkopírována, hlubší úrovně jsou odkazovány.,
# Deep Copy
Vezměme si stejný příklad, ale použití hluboké kopie pomocí „JSON“
jak vidíte, hluboká kopie je skutečnou kopií vnořených objektů. Často je mělká kopie dost dobrá, opravdu nepotřebujete hlubokou kopii. Je to jako hřebík zbraň vs kladivo. Většinou je kladivo naprosto v pořádku. Použití nehtové pistole pro některé malé umění a řemeslo je často případ nadměrné, kladivo je v pořádku. Je to všechno o použití správné nástroje pro správnou práci 🤓
# Výkon
Bohužel, nemohu napsat test pro šíření, protože to není oficiálně v spec., Přesto jsem ji zahrnul do testu, abyste ji mohli spustit v budoucnu 😝. Ale výsledek ukazuje Object.assign
je mnohem rychlejší než JSON
.
Test výkonu
# vstup komunity
# objekt.přiřadit vs šíření
@d9el: je důležité si uvědomit, že objekt.přiřazení je funkce, která modifikuje a vrací cílový objekt. V příkladu Samanthy pomocí následujícího,
const cloneFood = Object.assign({}, food);
{}
je objekt, který je upraven., Cílový objekt je neodkazují na žádnou proměnnou v tomto bodě, ale protože Object.assign
vrátí cílový objekt, jsme schopni uložit výsledný přiřazen objekt do cloneFood
proměnné. Mohli bychom vyměnit náš příklad a použijte následující:
const food = { beef: '🌽', bacon: '🥓' };Object.assign(food, { beef: '🥩' });console.log(food);// { beef: '🥩', bacon: '🥓' }
je Zřejmé, že hodnota beef
v našem jídlo objekt je špatně, takže můžeme přiřadit správnou hodnotu beef
pomocí Object.assign
., Nejsme použití vrácené hodnoty funkce na všech, ale my jsme úpravy našeho cílového objektu, který máme odkaz na const food
.
Spread na druhé straně je operátor, který kopíruje vlastnosti jednoho objektu do nového objektu., Pokud bychom chtěli zopakovat výše uvedený příklad pomocí rozšíření upravit naše proměnná food...
const food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};// TypeError: invalid assignment to const `food'
...
dostaneme chybu, protože používáme šíření při vytváření nových objektů, a proto jsou přiřazení zcela nový objekt, food
, který byl vyhlášen s const
, což je nezákonné., Tak můžeme si vybrat buď deklarovat novou proměnnou držet náš nový objekt, jako je následující:
const food = { beef: '🌽', bacon: '🥓' };const newFood = { ...food, beef: '🥩',};console.log(newFood);// { beef: '🥩', bacon: '🥓' }
nebo bychom mohli prohlásit, food
let
nebo var
což by nám umožnilo přiřadit zcela nový objekt:
let food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};console.log(food);// { beef: '🥩', bacon: '🥓' }
Díky: @d9el
# Hluboko Klon pomocí Externí Knihovny
# Více Způsobů, jak pomocí Javascriptu
- @hariharan_d3v :
Object.fromEntries(Object.entries(food))
klonů objektu.
Napsat komentář