Itu sangat tergantung pada apa yang ingin Anda klon. Apakah ini benar-benar objek JSON atau sembarang objek di JavaScript? Jika Anda ingin melakukan klon apa pun, itu mungkin membuat Anda mendapat masalah. Masalah yang mana? Saya akan menjelaskannya di bawah ini, tetapi pertama-tama, contoh kode yang mengkloning literal objek, primitif, array, dan node DOM.
function clone(item) {
if (!item) { return item; } // null, undefined values check
var types = [ Number, String, Boolean ],
result;
// normalizing primitives if someone did new String('aaa'), or new Number('444');
types.forEach(function(type) {
if (item instanceof type) {
result = type( item );
}
});
if (typeof result == "undefined") {
if (Object.prototype.toString.call( item ) === "[object Array]") {
result = [];
item.forEach(function(child, index, array) {
result[index] = clone( child );
});
} else if (typeof item == "object") {
// testing that this is DOM
if (item.nodeType && typeof item.cloneNode == "function") {
result = item.cloneNode( true );
} else if (!item.prototype) { // check that this is a literal
if (item instanceof Date) {
result = new Date(item);
} else {
// it is an object literal
result = {};
for (var i in item) {
result[i] = clone( item[i] );
}
}
} else {
// depending what you would like here,
// just keep the reference, or create new object
if (false && item.constructor) {
// would not advice to do that, reason? Read below
result = new item.constructor();
} else {
result = item;
}
}
} else {
result = item;
}
}
return result;
}
var copy = clone({
one : {
'one-one' : new String("hello"),
'one-two' : [
"one", "two", true, "four"
]
},
two : document.createElement("div"),
three : [
{
name : "three-one",
number : new Number("100"),
obj : new function() {
this.name = "Object test";
}
}
]
})
Dan sekarang, mari kita bicara tentang masalah yang mungkin Anda dapatkan saat mulai mengkloning objek REAL. Saya sekarang berbicara tentang objek yang Anda buat dengan melakukan sesuatu seperti
var User = function(){}
var newuser = new User();
Tentu saja Anda dapat mengkloningnya, itu bukan masalah, setiap objek mengekspos properti konstruktor, dan Anda dapat menggunakannya untuk mengkloning objek, tetapi itu tidak akan selalu berfungsi. Anda juga dapat melakukan sederhana for inpada objek ini, tetapi itu mengarah ke arah yang sama - masalah. Saya juga menyertakan fungsionalitas klon di dalam kode, tetapi dikecualikan oleh if( false )pernyataan.
Jadi, mengapa kloning bisa menyebalkan? Pertama-tama, setiap objek / instance mungkin memiliki beberapa status. Anda tidak pernah bisa yakin bahwa objek Anda tidak memiliki, misalnya variabel privat, dan jika demikian halnya, dengan mengkloning objek, Anda hanya memutus status.
Bayangkan tidak ada negara bagian, itu bagus. Lalu kami masih punya masalah lain. Kloning melalui metode "konstruktor" akan memberi kita kendala lain. Ini adalah ketergantungan argumen. Anda tidak pernah bisa yakin, bahwa seseorang yang menciptakan objek ini, tidak melakukannya, semacam
new User({
bike : someBikeInstance
});
Jika ini masalahnya, Anda kurang beruntung, someBikeInstance mungkin dibuat dalam beberapa konteks dan konteks tersebut tidak diketahui untuk metode klon.
Lalu apa yang harus dilakukan? Anda masih dapat melakukan for insolusi, dan memperlakukan objek seperti itu seperti objek literal normal, tetapi mungkin ide untuk tidak mengkloning objek tersebut sama sekali, dan hanya meneruskan referensi objek ini?
Solusi lainnya adalah - Anda dapat menyetel konvensi bahwa semua objek yang harus digandakan harus mengimplementasikan bagian ini sendiri dan menyediakan metode API yang sesuai (seperti cloneObject). Sesuatu yang cloneNodedilakukan untuk DOM.
Kamu putuskan.