"Javascript klon nesnesi" için googling bazı gerçekten garip sonuçlar getiriyor, bazıları umutsuzca modası geçmiş ve bazıları çok karmaşık, o kadar kolay değil:
let clone = {...original};
Bunda yanlış bir şey var mı?
"Javascript klon nesnesi" için googling bazı gerçekten garip sonuçlar getiriyor, bazıları umutsuzca modası geçmiş ve bazıları çok karmaşık, o kadar kolay değil:
let clone = {...original};
Bunda yanlış bir şey var mı?
Yanıtlar:
Bu sığ klonlama için iyidir . Nesne yayılması ECMAScript'e 2018 standart bir parçası olduğunu .
Derin klonlama için farklı bir çözüme ihtiyacınız olacak .
const clone = {...original}
sığ klonlamak
const newobj = {...original, prop: newOne}
orijinaline değişmez bir şekilde başka bir pervane eklemek ve yeni bir nesne olarak saklamak.
JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
çalışmaz, çünkü orada functions
ya infinity
da değer olarak null
kendi yerine atar . Yalnızca değerler basitse literals
ve değilse çalışır functions
.
DÜZENLE: Bu yanıt gönderildiğinde, {...obj}
sözdizimi çoğu tarayıcıda mevcut değildi. Günümüzde (IE 11'i desteklemeniz gerekmedikçe) bunu kullanmalısınız.
Object.assign öğesini kullanın.
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 }
Ancak, bu derin bir klon oluşturmaz. Henüz derin klonlamanın doğal bir yolu yok.
DÜZENLEME: @Mike 'Pomax' Kamermans'ın yorumlarda belirtildiği gibi, basit nesneleri (yani, prototip, fonksiyon veya dairesel referans yok) kullanarak klonlayabilirsiniz. JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
uygun bir derin klon. Bununla birlikte, prototipler, fonksiyonlar veya dairesel referanslar yürürlükte olduğu anda, bu çözüm artık çalışmaz.
Kullandığınız yöntemler Date gibi veri türlerini içeren nesnelerle iyi çalışmıyorsa bunu deneyin
İthalat _
import * as _ from 'lodash';
Derin klon nesnesi
myObjCopy = _.cloneDeep(myObj);
import _ from 'lodash';
yeter. Ancak +1 "tekerleği yeniden icat etme" yanıtı için.
json.parse (json.stringify (object)) kullanmak istemiyorsanız, yinelenen anahtar / değer kopyaları oluşturabilirsiniz:
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;
}
Ama en iyi yol, kendisinin bir klonunu döndürebilen bir sınıf yaratmaktır
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'in cevabından sonra klonlanmış nesnede bazı fonksiyonların hala eksik olduğunu gördüm. Örneğin
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 || {};
}
});
}
burada MyObject üzerinde methodA klonlayabilirdim ama methodB hariç tutuldu. Bu, eksik olduğu için oluştu
enumerable: true
bu demek değil ki
for(let key in item)
Bunun yerine
Object.getOwnPropertyNames(item).forEach((key) => {
....
});
numaralandırılamayan anahtarları içerir.
Ayrıca prototipin ( proto ) klonlanmadığını gördüm . Bunun için kullanarak
if (obj.__proto__) {
copy.__proto__ = Object.assign(Object.create(Object.getPrototypeOf(obj)), obj);
}
Not: Bunu yapmak için yerleşik bir işlev bulamadığım için sinir bozucu.
Sen de böyle yapabilirsin,
let copiedData = JSON.parse(JSON.stringify(data));
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.
Ancak Object.assign () derin bir klon oluşturmaz
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
Bunu düzeltmek için, kullanıcı [anahtar] 'ın her değerini inceleyen klonlama döngüsünü kullanmalıyız ve eğer bir nesne ise yapısını da çoğaltırız. Buna “derin klonlama” denir.
Yukarıdaki durumu ele alan standart bir algoritma ve Yapısal klonlama algoritması adı verilen daha karmaşık vakalar vardır . Tekerleği yeniden icat etmemek için, yöntemin _.cloneDeep (obj) adı verilen JavaScript kütüphanesinden çalışan bir uygulamasını kullanabiliriz .
Yukarıdaki tüm yöntemler, n seviyesine yerleştirildiği nesnelerin derin klonlanmasını işlemez. Performansını diğerlerine göre kontrol etmedim ama kısa ve basit.
Aşağıdaki ilk örnek, Object.assign
ilk seviyeye kadar hangi klonları kullanarak nesne klonlamasını gösterir .
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
Aşağıdaki yaklaşımı kullanarak derin klonlar nesnesi
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
original = { a: [1,2,3] }
sizeclone.a
tam anlamıyla var olan bir klon veriroriginal.a
. Ya yoluyla Modifikasyonclone
veyaoriginal
tuşelere aynı şey , bu yüzden hayır, bu) kötü = olduğunu