이것이 ES6에서 개체를 복제하는 좋은 방법입니까?
"javascript clone object"를 검색하면 정말 이상한 결과를 얻을 수 있습니다. 일부는 구제불능으로 구식이고 일부는 너무 복잡합니다. 다음과 같이 쉽습니다.
let clone = {...original};
이것에 무슨 문제가 있습니까?
이것은 얕은 복제에 좋습니다.개체 스프레드는 ECMA스크립트 2018의 표준 부분입니다.
심층 복제를 위해서는 다른 솔루션이 필요합니다.
const clone = {...original}
천박한 클론
const newobj = {...original, prop: newOne}
원본에 다른 소품을 불변으로 추가하고 새 물건으로 저장합니다.
편집: 이 답변이 게시되었을 때,{...obj}
구문을 대부분의 브라우저에서 사용할 수 없습니다.요즘에는 IE 11을 지원할 필요가 없는 한 사용해도 괜찮습니다.
Object.assign을 사용합니다.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
하지만, 이것은 딥 클론이 되지는 않을 것입니다.딥 클로닝의 네이티브 방법은 아직 없습니다.
편집: 댓글에서 @Mike 'Pomax' Kamermans가 언급했듯이, 당신은 다음을 사용하여 간단한 객체(즉, 프로토타입, 기능 또는 순환 참조 없음)를 딥 클론할 수 있습니다.JSON.parse(JSON.stringify(input))
사용한 방법이 날짜와 같은 데이터 유형이 포함된 개체에서 제대로 작동하지 않는 경우 다음을 시도하십시오.
수입품_
import * as _ from 'lodash';
딥 클론 개체
myObjCopy = _.cloneDeep(myObj);
이렇게 할 수도 있고요.
let copiedData = JSON.parse(JSON.stringify(data));
json.dll(json.stringify(object))을 사용하지 않으려면 키 값 복사본을 재귀적으로 만들 수 있습니다.
function copy(item){
let result = null;
if(!item) return result;
if(Array.isArray(item)){
result = [];
item.forEach(element=>{
result.push(copy(element));
});
}
else if(item instanceof Object && !(item instanceof Function)){
result = {};
for(let key in item){
if(key){
result[key] = copy(item[key]);
}
}
}
return result || item;
}
그러나 가장 좋은 방법은 자신의 복제본을 반환할 수 있는 클래스를 만드는 것입니다.
class MyClass{
data = null;
constructor(values){ this.data = values }
toString(){ console.log("MyClass: "+this.data.toString(;) }
remove(id){ this.data = data.filter(d=>d.id!==id) }
clone(){ return new MyClass(this.data) }
}
@marcel의 답변에 이어 복제된 개체에서 일부 함수가 누락된 것을 발견했습니다.
function MyObject() {
var methodAValue = null,
methodBValue = null
Object.defineProperty(this, "methodA", {
get: function() { return methodAValue; },
set: function(value) {
methodAValue = value || {};
},
enumerable: true
});
Object.defineProperty(this, "methodB", {
get: function() { return methodAValue; },
set: function(value) {
methodAValue = value || {};
}
});
}
MyObject에서 메소드 A를 복제할 수 있지만 메소드 B는 제외되었습니다.누락되어 발생했습니다.
enumerable: true
그 말은 그것이 에 나타나지 않았다는 것을 의미했습니다.
for(let key in item)
대신에 저는 로 바꿨습니다.
Object.getOwnPropertyNames(item).forEach((key) => {
....
});
삭제할 수 없는 키가 포함됩니다.
프로토타입(프로토토)이 복제되지 않은 것도 발견했습니다.그것을 위해 저는 사용하게 되었습니다.
if (obj.__proto__) {
copy.__proto__ = Object.assign(Object.create(Object.getPrototypeOf(obj)), obj);
}
PS: 이것을 할 수 있는 내장된 기능을 찾을 수 없어서 실망스럽습니다.
구조화된 클론 이 방법을 사용할 수 있습니다.
function Copy_Object(obj) { return structuredClone(obj); }
업데이트: 2023년 5월 31일 window.structuredClone()이라는 DEEP COPY를 허용하는 새로운 글로벌 기능이 릴리스되었습니다.
const person1 = {
address: {
address1: "my address1",
address2: "my address2"
},
age: 23
};
console.log(person1)
const person2 = window.structuredClone(person1)
person2.address.address1 = "my new address1"
person2.address.address2= "my new address2"
person2.age = 40
console.log(person1) // person1 was not changed
We can do that with two way:
1- First create a new object and replicate the structure of the existing one by iterating
over its properties and copying them on the primitive level.
let user = {
name: "John",
age: 30
};
let clone = {}; // the new empty object
// let's copy all user properties into it
for (let key in user) {
clone[key] = user[key];
}
// now clone is a fully independant clone
clone.name = "Pete"; // changed the data in it
alert( user.name ); // still John in the original object
2- Second we can use the method Object.assign for that
let user = { name: "John" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };
// copies all properties from permissions1 and permissions2 into user
Object.assign(user, permissions1, permissions2);
-Another example
let user = {
name: "John",
age: 30
};
let clone = Object.assign({}, user);
It copies all properties of user into the empty object and returns it. Actually, the same as the loop, but shorter.
그러나 Object.assign()이(가) 딥 클론을 생성하지 않습니다.
let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
let clone = Object.assign({}, user);
alert( user.sizes === clone.sizes ); // true, same object
// user and clone share sizes
user.sizes.width++; // change a property from one place
alert(clone.sizes.width); // 51, see the result from the other one
이 문제를 해결하려면 사용자[키]의 각 값을 검사하고 개체인 경우 해당 구조를 복제하는 복제 루프를 사용해야 합니다.그것은 "딥 클로닝"이라고 불립니다.
위의 경우와 더 복잡한 경우를 처리하는 딥 클로닝을 위한 표준 알고리즘이 있는데, 이를 구조화 클로닝 알고리즘이라고 합니다.휠을 재창조하지 않기 위해 _.cloneDeep(obj)라고 하는 방법을 JavaScript 라이브러리 lodash에서 실행 중인 구현을 사용할 수 있습니다.
기능도 복사할 수 있는 솔루션을 찾았습니다. 이 예시가 오류라면 수정해 주세요.
주의: 더 복잡한 객체 사례를 사용하여 이 방법을 테스트하지 않았습니다. 예를 들어, 참조를 위해 이 방법을 포함하는 방법이 포함됩니다.
아침 식사 가격을 예로 들어 보겠습니다. 전 세계적으로 이 가격을 사용할 수 있지만 호텔 객실에 대해 개별적으로 조정하고 싶습니다.
// make an object for a booking option
var opt_resa = { breakfast_val: 900 }
// i define a function for opt_resa :
opt_resa.func = function(){ alert('i am a function'); }
// copy object in modif.opt_resa :
var modif = { opt_resa : {} }
for ( var v in opt_resa ){
modif.opt_resa[v] = opt_resa[v];
}
// test
modif.opt_resa.breakfast_val = 1500;
// old value
console.log( opt_resa.breakfast_val );
// output : 900
// modified value
console.log( modif.opt_resa.breakfast_val );
// output : 1500
// function copied
modif.opt_resa.func();
// this function works
위의 모든 메소드는 n개 수준에 중첩된 개체의 심층 복제를 처리하지 않습니다.저는 다른 사람들보다 성능을 확인하지 않았지만 짧고 간단합니다.
아래의 첫 번째 예는 다음을 사용하여 개체를 복제하는 방법을 보여 줍니다.Object.assign
1단계까지만 복제가 가능합니다.
var person = {
name:'saksham',
age:22,
skills: {
lang:'javascript',
experience:5
}
}
newPerson = Object.assign({},person);
newPerson.skills.lang = 'angular';
console.log(newPerson.skills.lang); //logs Angular
아래 접근 방식을 사용하는 딥 클론 개체
var person = {
name:'saksham',
age:22,
skills: {
lang:'javascript',
experience:5
}
}
anotherNewPerson = JSON.parse(JSON.stringify(person));
anotherNewPerson.skills.lang = 'angular';
console.log(person.skills.lang); //logs javascript
언급URL : https://stackoverflow.com/questions/39736397/is-this-a-good-way-to-clone-an-object-in-es6
'programing' 카테고리의 다른 글
Ajax/jquery 호출의 성공 함수 외부 변수 사용 (0) | 2023.08.17 |
---|---|
CSS를 사용하여 Ul 들여쓰기 제거 (0) | 2023.08.17 |
로컬 저장소에 개체 저장 (0) | 2023.08.17 |
특정 사용자로부터 순위, 이름 및 점수를 얻기 위한 SQL 쿼리 (0) | 2023.08.17 |
MariaDB 이미 시스템 버전 테이블 처리 방법 (0) | 2023.08.17 |