JavaScriptã®æµ ãã³ããŒãšæ·±ãã³ããŒã®éããããããããæŽçããŸããã
JavaScriptã§éçºããŠãããšããªããžã§ã¯ããã³ããŒããªããã°ãªããªãç¶æ³ãé »ç¹ã«çºçããŸããã§ãåçŽã« = æŒç®åã§ã³ããŒãããšãæããããªããã°ãåŒãèµ·ããããšããããŸãããªããªããªããžã§ã¯ãã¯åç
§åã ããã§ãã
ãã®èšäºã§ã¯æµ ãã³ããŒãšæ·±ãã³ããŒã®éããããããã®äœ¿çšã±ãŒã¹ããããŠå®åã§ä»ãã䜿ããå®è£ æ¹æ³ã解説ããŸãã
æµ ãã³ããŒïŒShallow CopyïŒãšã¯ïŒ
æµ ãã³ããŒã¯ãªããžã§ã¯ãã®æäžäœã®ããããã£ã ããã³ããŒããæ¹åŒã§ããã³ããŒããããªããžã§ã¯ããšå ã®ãªããžã§ã¯ãã åãåç §ãå ±æããããããã¹ãããããªããžã§ã¯ããä¿®æ£ãããšå ã«ã圱é¿ãåºãŸãã
æµ ãã³ããŒã®åäœåç
æµ
ãã³ããŒãè¡ããšæ°ãããªããžã§ã¯ããçæãããŸãïŒo1 !== o2ïŒããå
éšã®ãã¹ãããããªããžã§ã¯ããé
åã¯åãã¡ã¢ãªã¢ãã¬ã¹ãæããŸãã
const original = {
name: "íêžžë",
age: 30,
address: {city: "ììž",district: "ê°ëšêµ¬"
}
};
const shallowCopy = Object.assign({}, original);
// æäžäœããããã£ã®å€æŽ â å
ã«åœ±é¿ãªã
shallowCopy.name = "ê¹ì² ì";
console.log(original.name); // "íêžžë"
// ãã¹ãããããªããžã§ã¯ãã®å€æŽ â å
ã«ã圱é¿ïŒ
shallowCopy.address.city = "ë¶ì°";
console.log(original.address.city); // "ë¶ì°"
æµ ãã³ããŒå®è£ æ¹æ³
JavaScriptã§æµ ãã³ããŒãè¡ãæ¹æ³ã¯ããã€ããããŸãïŒ
1. Object.assign()ã䜿çš
const user = {
name: "ê¹ë¯Œì",
role: "ê°ë°ì"
};
const clone = Object.assign({}, user);
2. ã¹ãã¬ããæ§æïŒSpread SyntaxïŒã䜿çš
const user = {
name: "ë°ì§ì",
role: "ëììŽë"
};
const clone = { ...user };
3. é åã®å Žå
const items = [1, 2, { value: 3 }];
// Array.from()
const copy1 = Array.from(items);
// slice()
const copy2 = items.slice();
// concat()
const copy3 = [].concat(items);
// ã¹ãã¬ããæ§æ
const copy4 = [...items];
æµ ãã³ããŒã®ç¹åŸŽ
æµ ãã³ããŒããããªããžã§ã¯ãã®æäžäœã®ããããã£ãåä»£å ¥ããŠãå ã®ãªããžã§ã¯ãã«ã¯åœ±é¿ãäžããŸããããããããã¹ãããããªããžã§ã¯ãã®ããããã£ã倿Žãããšå ã®ãªããžã§ã¯ããäžç·ã«å€æŽãããŸãã
const ingredientsList = ["êµì", { list: ["ê³ë", "ë°ê°ë£š", "묌"] }];
const ingredientsListCopy = Array.from(ingredientsList);
// æäžäœèŠçŽ ã®å€æŽ
ingredientsListCopy[0] = "ìêµì";
console.log(ingredientsList[0]); // "êµì"ïŒåœ±é¿ãªãïŒ
// ãã¹ãããããªããžã§ã¯ãã®å€æŽ
ingredientsListCopy[1].list = ["ìê°ë£š", "묌"];
console.log(ingredientsList[1].list); // ["ìê°ë£š", "묌"]ïŒåœ±é¿ããïŒïŒ
æ·±ãã³ããŒïŒDeepâ¯CopyïŒãšã¯ïŒ
æ·±ãã³ããŒã¯ãªããžã§ã¯ãã®ãã¹ãŠã®ãã¹ããããããããã£ãŸã§å®å šã«æ°ããã³ããŒãäœãæ¹åŒã§ããã³ããŒæ¬äœãä¿®æ£ããŠãå ã®ãªããžã§ã¯ãã«ã¯å šã圱é¿ãäžããŸããã
æ·±ãã³ããŒã®å®çŸ©
äºã€ã®ãªããžã§ã¯ããæ·±ãã³ããŒé¢ä¿ã«ããããã«ã¯ãæ¬¡ã®æ¡ä»¶ãæºãããªããã°ãªããŸããïŒ
- äºã€ã®ãªããžã§ã¯ãã¯å¥åã®ãªããžã§ã¯ãã§ããããš (
o1 !== o2) - ããããã£ã®ååãšé åºãåãã§ããããš
- ããããã£ã®å€ãããããã®æ·±ãã³ããŒã§ããããš
- ãããã¿ã€ããã§ãŒã³ãæ§é çã«åäžã§ããããš
æ·±ãã³ããŒã®åäœåç
æ·±ãã³ããŒã¯ãã¹ãããããã¹ãŠã®ãªããžã§ã¯ããååž°çã«ã³ããŒããŸãããããã£ãŠãã³ããŒæ¬äœã®ã©ãã倿ŽããŠãå ã«ã¯åœ±é¿ãäžããŸããã
const original = {
name: "ìŽìì§",
projects: {current: ["íë¡ì íž A", "íë¡ì íž B"],completed: ["íë¡ì íž X"]
}
};
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.projects.current.push("íë¡ì ížâ¯C");
console.log(original.projects.current); // ["íë¡ì íž A", "íë¡ì íž B"]ïŒåœ±é¿ãªãïŒ
æ·±ãã³ããŒå®è£ æ¹æ³
1. JSON.parse(JSON.stringify())ãæŽ»çš
ãã£ãšãç°¡åã§åºã䜿ãããæ¹æ³ã§ãã
const ingredientsList = ["êµì", { list: ["ê³ë", "ë°ê°ë£š", "묌"] }];
const ingredientsListDeepCopy = JSON.parse(JSON.stringify(ingredientsList));
ingredientsListDeepCopy[1].list = ["ìê°ë£š", "묌"];
console.log(ingredientsList[1].list); // ["ê³ë", "ë°ê°ë£š", "묌"]ïŒåœ±é¿ãªãïŒ
é·æ:
- å®è£ ãç°¡åã§çŽæçã§ã
- å¥ã®ã©ã€ãã©ãªãäžèŠã§ã
çæ:
- 颿°ã¯ã³ããŒãããŸãã
Dateãªããžã§ã¯ãã¯æååã«å€æãããŸãundefinedãSymbolãšãã£ãç¹æ®å€ã¯ç¡èŠãããŸã- 埪ç°åç §ããããšãšã©ãŒã«ãªããŸã
const obj = {
date: new Date(),
func: () => console.log("hello"),
undef: undefined
};
const copy = JSON.parse(JSON.stringify(obj));
console.log(copy);
// { date: "2024â01â15T10:30:00.000Z" }
// funcãšundefã¯æ¶ããŸã
2. structuredClone()ã®äœ¿çš
JavaScriptãæšæºã§æäŸããã¡ãœããã§ãã
const original = {
name: "ìµì ì§",
date: new Date(),
nested: {data: [1, 2, 3]
}
};
const deepCopy = structuredClone(original);
deepCopy.nested.data.push(4);
console.log(original.nested.data); // [1, 2, 3]ïŒåœ±é¿ãªãïŒ
console.log(deepCopy.date instanceof Date); // true
é·æ:
Date,RegExp,Map,Setãªã©å€æ§ãªçµã¿èŸŒã¿ãªããžã§ã¯ããæ£ç¢ºã«ã³ããŒããŸã- 埪ç°åç §ãæ±ããŸã
- ããã©ãŒãã³ã¹ãåªããŠããŸã
çæ:
- 颿°ã¯ãã¯ãã³ããŒãããŸãã
- å€ããã©ãŠã¶ã§ã¯ãµããŒããããŠããªãå¯èœæ§ããããŸã
3. ååž°é¢æ°ã䜿ã£ãã«ã¹ã¿ã å®è£
å®å šãªå¶åŸ¡ãå¿ èŠãªå Žåã¯èªåã§å®è£ ã§ããŸãã
function deepClone(obj, hash = new WeakMap()) {
// nullãŸãã¯åå§åãªããã®ãŸãŸè¿ã
if (obj === null || typeof obj !== 'object') {return obj;
}
// 埪ç°åç
§åŠç
if (hash.has(obj)) {return hash.get(obj);
}
// Date, RegExp çã®ç¹å¥ãªãªããžã§ã¯ãåŠç
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
// æ°ãããªããžã§ã¯ãäœæ
const cloneObj = Array.isArray(obj) ? [] : {};
hash.set(obj, cloneObj);
// ååž°çã«ã³ããŒ
for (let key in obj) {if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key], hash);}
}
return cloneObj;
}
const original = {
name: "ì 믌íž",
skills: ["JavaScript", "React"],
experience: {years: 5,companies: ["Aì¬", "Bì¬"]
}
};
const copy = deepClone(original);
copy.skills.push("TypeScript");
console.log(original.skills); // ["JavaScript", "React"]ïŒåœ±é¿ãªãïŒ
é·æ:
- å¿ èŠã«å¿ããŠã«ã¹ã¿ãã€ãºå¯èœã§ã
- ç¹æ®ãªåãæã圢ã§å¯Ÿå¿ã§ããŸã
çæ:
- å®è£ ãšä¿å®ãè€éã§ã
- å šãŠã®ãšããžã±ãŒã¹ãèæ ®ããå¿ èŠããããŸã
4. Lodashã©ã€ãã©ãªæŽ»çš
Lodash ã¯å®åã§ãã䜿ãããJavaScriptãŠãŒãã£ãªãã£ã©ã€ãã©ãªã§ãã
import _ from 'lodash';
const original = {
name: "ê°ìì°",
metadata: {tags: ["frontend", "react"],createdAt: new Date()
}
};
const deepCopy = _.cloneDeep(original);
é·æ:
- æ€èšŒæžã¿ã®å®è£ ã§å®å®ããŠããŸã
- å€ãã®ãšããžã±ãŒã¹ãåŠçããŸã
çæ:
- 远å ã®ã©ã€ãã©ãªãã€ã³ã¹ããŒã«ããå¿ èŠããããŸã
- ãã³ãã«ãµã€ãºãå¢ããå¯èœæ§ããããŸãïŒãã¡ãã lodash ã®å®¹éã巚倧ãšããããã§ã¯ãããŸãããâŠïŒ
ãã€æµ ãã³ããŒã䜿ããïŒ
æµ ãã³ããŒã¯æ¬¡ã®ãããªç¶æ³ã«é©ããŠããŸãïŒ
1. ããã©ãŒãã³ã¹ãéèŠãªå Žå
ãã¹ãããããªããžã§ã¯ããåå¥ã«ä¿®æ£ããå¿ èŠããªããã°ãæµ ãã³ããŒã®ã»ããéããŠã¡ã¢ãªå¹çãé«ãã§ãã
const userConfig = {
theme: "dark",
language: "ko"
};
// æäžäœããããã£ã ã倿Žããã®ã§æµ
ãã³ããŒã§åå
const newConfig = { ...userConfig, theme: "light" };
2. æäžäœããããã£ã ã倿Žããå Žå
ãã¹ãããããªããžã§ã¯ããè§Šããªããªãæµ ãã³ããŒã ãã§ãååã§ãã
const product = {
id: 1,
name: "ë
žížë¶",
price: 1500000
};
const updatedProduct = { ...product, price: 1400000 };
3. Reactã§ã®PropsäŒéæ
Reactã§ã¯äžå€æ§ãä¿ã€ããã«æµ ãã³ããŒãé »ç¹ã«äœ¿ããŸãã
const handleUpdate = (newData) => {
setUser({ ...user, ...newData });
};
ãã€æ·±ãã³ããŒã䜿ããïŒ
æ·±ãã³ããŒã¯æ¬¡ã®ãããªç¶æ³ã§å¿ èŠã§ãïŒ
1. å®å šã«ç¬ç«ããã³ããŒãå¿ èŠãªå Žå
å ãšãŸã£ããåé¢ããããªããžã§ã¯ããå¿ èŠãªãšãã«ãæ·±ãã³ããŒã䜿ããŸãã
const template = {
title: "Ʞ볞 í
í늿",
sections: [{ type: "header", content: "ì 목" },{ type: "body", content: "볞묞" }
]
};
// åãŠãŒã¶ãŒããšã«ç¬ç«ãããã³ãã¬ãŒããå¿
èŠ
const userTemplate = structuredClone(template);
userTemplate.sections[0].content = "ì¬ì©ì ì 목";
2. ãã¹ãããããªããžã§ã¯ããä¿®æ£ããªããã°ãªããªãå Žå
è€éãªããŒã¿æ§é ãæ±ãéã«ã¯æ·±ãã³ããŒãå¿ èŠã§ãã
const projectData = {
name: "ì ê· íë¡ì íž",
team: {frontend: ["ê¹ê°ë°", "ìŽëììž"],backend: ["ë°ìë²", "ìµëë¹"]
}
};
const archivedProject = structuredClone(projectData);
archivedProject.team.frontend.push("ì ì
ì¬ì");
// originalã®teamã«ã¯åœ±é¿ãªã
3. ç¶æ å±¥æŽã管çããå Žå
ãå®è¡åãæ¶ãïŒUndoïŒãæ©èœãå®è£ ããéã«æçšã§ãã
const history = [];
function saveState(currentState) {
history.push(structuredClone(currentState));
}
function undo() {
return history.pop();
}
ããã©ãŒãã³ã¹èæ ®äºé
æ·±ãã³ããŒãšæµ ãã³ããŒã§ã¯ããã©ãŒãã³ã¹ã«å·®ããããŸãã
æµ ãã³ããŒã®ããã©ãŒãã³ã¹
æµ ãã³ããŒã¯æäžäœããããã£ã ããã³ããŒããããéåžžã«éãã§ãããªããžã§ã¯ãã®ãµã€ãºã倧ããã»ã©ãæ·±ãã³ããŒã«æ¯ã¹ãŠã¡ãªããã倧ãããªããŸãã
// éã
const shallowCopy = { ...largeObject };
æ·±ãã³ããŒã®ããã©ãŒãã³ã¹
æ·±ãã³ããŒã¯ãã¹ãŠã®ãã¹ãæ§é ãå·¡åãããããåœç¶ãªããåŠçæéãé·ããªããŸãã
// æ¯èŒçé
ã
const deepCopy = structuredClone(largeObject);
ããã©ãŒãã³ã¹æé©åã®ãã³ã
å€§èŠæš¡ãªãªããžã§ã¯ããæ±ããšãã¯æ¬¡ãæ€èšããŠãã ããïŒ
- å¿ èŠãªéšåã ãã³ããŒãã
const { metadata, ...essentialData } = largeObject;
const copy = structuredClone(essentialData);
- ã¡ã¢åïŒMemoizationïŒã掻çš
const cache = new WeakMap();
function getCachedCopy(obj) {
if (!cache.has(obj)) {cache.set(obj, structuredClone(obj));
}
return cache.get(obj);
}
- é©åãªæ¹æ³ãéžæãã
- ã·ã³ãã«ãªãªããžã§ã¯ãïŒ
JSON.parse(JSON.stringify()) - è€éãªãªããžã§ã¯ãïŒ
structuredClone() - ã«ã¹ã¿ã ããžãã¯ãå¿ èŠïŒèªåã§å®è£ ããããŸã㯠Lodash
ãããã質å
Q: é åãåãæ¹åŒã§ã³ããŒããã®ã§ããïŒ
ã¯ããé
åããªããžã§ã¯ããªã®ã§åãåçãé©çšãããŸããæµ
ãã³ããŒãªãã¹ãã¬ããæ§æã slice() ããæ·±ãã³ããŒãªã structuredClone() ã䜿ããšè¯ãã§ãã
Q: Reactã§ã¯ã©ã®ã³ããŒæ¹åŒãäž»ã«äœ¿ãããŠããŸããïŒ
Reactã§ã¯ã»ãšãã©ã®å Žåãæµ
ãã³ããŒã䜿çšãããŸããç¶æ
æŽæ°æã« { ...state } ã®ããã«æ°ãããªããžã§ã¯ããäœã£ãŠäžå€æ§ãä¿ã¡ãŸãã
Q: JSONæ¹åŒã®æ·±ãã³ããŒã§ååã§ã¯ãªãã®ã§ããïŒ
åçŽãªããŒã¿æ§é ã«ã¯ååã§ãããDateã颿°ãundefined ãªã©ãæ±ãå¿
èŠããããªã structuredClone() ã Lodash ã䜿ãã»ããè¯ãæ¹æ³ã§ãïŒ