Gerçekten ne klonlamak istediğinize bağlı. Bu gerçekten bir JSON nesnesi mi yoksa JavaScript'teki herhangi bir nesne mi? Herhangi bir klon yapmak isterseniz, başınızı belaya sokabilir. Hangi sorun? Aşağıda açıklayacağım, ancak önce nesne değişmezlerini, ilkelleri, dizileri ve DOM düğümlerini klonlayan bir kod örneği.
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";
}
}
]
})
Şimdi de GERÇEK nesneleri klonlamaya başladığınızda karşılaşabileceğiniz problemlerden bahsedelim. Şimdi konuşuyorum, benzer bir şey yaparak yarattığınız nesnelerden bahsediyorum
var User = function(){}
var newuser = new User();
Elbette onları klonlayabilirsiniz, bu bir problem değildir, her nesne yapıcı özelliğini açığa çıkarır ve nesneleri klonlamak için kullanabilirsiniz, ancak bu her zaman çalışmayacaktır. for inBu nesneler üzerinde basit de yapabilirsiniz , ancak aynı yöne gider - sorun. Kodun içine klonlama işlevini de ekledim, ancak if( false )ifade tarafından hariç tutuldu .
Öyleyse klonlama neden bir acı olabilir? Her şeyden önce, her nesnenin / örneğin bir durumu olabilir. Nesnelerinizin, örneğin özel değişkenlere sahip olmadığından asla emin olamazsınız ve bu durumda, nesneyi klonlayarak, durumu kırarsınız.
Devletin olmadığını hayal edin, sorun değil. O halde hala başka bir sorunumuz var. "Oluşturucu" yöntemiyle klonlamak bize başka bir engel oluşturacaktır. Bu bir argüman bağımlılığıdır. Bu nesneyi yaratan birinin yapmadığından asla emin olamazsınız, bir tür
new User({
bike : someBikeInstance
});
Durum buysa, şansınız kalmaz, someBikeInstance muhtemelen bir bağlamda oluşturulmuştur ve bu bağlam klon yöntemi için bilinmemektedir.
Peki ne yapmalı? Hala for inçözüm yapabilir ve bu tür nesnelere normal nesne değişmezleri gibi davranabilirsiniz, ancak bu tür nesneleri hiç klonlamamak ve sadece bu nesnenin referansını geçmek bir fikir olabilir mi?
Başka bir çözüm de - klonlanması gereken tüm nesnelerin bu bölümü kendi başlarına uygulaması ve uygun API yöntemini (cloneObject gibi) sunması için bir kural belirleyebilirsiniz. cloneNodeDOM için yapılan bir şey .
Sen karar ver.