Bir JavaScript nesnesini do─čru ┼čekilde klonlayabilir miyim?


Al─▒nan cevaba git


Benim bir nesnem var x . De─či┼čtirmek y i├žin de─či┼čiklik y yapacak ┼čekilde nesne olarak kopyalamak istiyorum x . Yerle┼čik JavaScript nesnelerinden t├╝retilmi┼č nesnelerin kopyalanmas─▒n─▒n, ekstra ve istenmeyen ├Âzelliklere neden olaca─č─▒n─▒ fark ettim. Bu bir sorun de─čil, ├ž├╝nk├╝ kendi kendime ait haz─▒r nesnelerden birini kopyal─▒yorum.

Bir JavaScript nesnesini do─čru ┼čekilde klonlayabilir miyim?


2890









Cevap say─▒s─▒n─▒ say: 30






Bunu JavaScript'teki herhangi bir nesne i├žin yapmak basit veya kolay olmayacakt─▒r. Nesnenin prototipinden prototip i├žinde b─▒rak─▒lmas─▒ ve yeni ├Ârne─če kopyalanmamas─▒ i├žin hatal─▒ nitelikler toplama problemiyle kar┼č─▒la┼čacaks─▒n─▒z. ├ľrne─čin, bir ekliyorsan─▒z clone y├Ântemi i├žin Object.prototype baz─▒ cevaplar tasvir gibi, a├ž─▒k├ža o niteli─či atlamak gerekir. Ancak Object.prototype , bilmedi─činiz ba┼čka ilave y├Ântemler veya di─čer orta prototipler varsa ne olacak? Bu durumda, yapmaman─▒z gereken ├Âzellikleri kopyalayacaks─▒n─▒z, bu nedenle ├Âng├Âr├╝lemeyen, yerel olmayan ├Âzellikleri hasOwnProperty y├Ântemle saptaman─▒z gerekir .

Numaraland─▒r─▒lamayan ├Âzelliklere ek olarak, gizli ├Âzelliklere sahip nesneleri kopyalamaya ├žal─▒┼čt─▒─č─▒n─▒zda daha zor bir sorunla kar┼č─▒la┼č─▒rs─▒n─▒z. ├ľrne─čin, prototype bir i┼člevin gizli bir ├Âzelli─čidir. Ayr─▒ca, bir nesnenin prototipine, __proto__ ayn─▒ zamanda gizli olan ve kaynak nesnenin ├Âzniteliklerini yineleyen for / in d├Âng├╝s├╝nde kopyalanmayacak olan ├Âznitelik g├Âsterilir. Bence __proto__ Firefox'un JavaScript yorumlay─▒c─▒s─▒ ├Âzg├╝ olabilir ve di─čer taray─▒c─▒larda farkl─▒ bir ┼čey olabilir, ama resmi olsun. Her ┼čey numaraland─▒r─▒labilir de─čil. Ad─▒n─▒ biliyorsan─▒z gizli bir niteli─či kopyalayabilirsiniz, ancak otomatik olarak ke┼čfetmenin bir yolunu bilmiyorum.

Zarif bir ├ž├Âz├╝m aray─▒┼č─▒ndaki bir ba┼čka engel, prototip miras─▒n─▒ do─čru ayarlama problemidir. Kaynak nesnenizin prototipi ise Object , o zaman basit bir ┼čekilde yeni bir genel nesne olu┼čturmak {} i┼če yarayacakt─▒r, ancak kayna─č─▒n prototipi biraz soyundan Object geliyorsa, o zaman hasOwnProperty filtreyi kullanarak atlad─▒─č─▒n─▒z veya prototipten ek ├╝yeleriniz eksik olacakt─▒r. prototip i├žerisindeydiler, ancak ilk s─▒rada numaraland─▒r─▒lm─▒yorlard─▒. ├ç├Âz├╝mlerden biri constructor , ilk kopya nesnesini almak i├žin kaynak nesnenin ├Âzelli─čini ├ža─č─▒rmak ve ard─▒ndan niteliklerin ├╝zerine kopyalamak olabilir, ancak yine de numaraland─▒r─▒lamayan ├Âzellikleri alamazs─▒n─▒z. ├ľrne─čin, bir Date nesne verilerini gizli bir ├╝ye olarak saklar:

 function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
    }
    return copy;
}

var d1 = new Date();

/* Executes function after 5 seconds. */
setTimeout(function(){
    var d2 = clone(d1);
    alert("d1 = " + d1.toString() + "\nd2 = " + d2.toString());
}, 5000);
 

Tarih dizesi, d1 5 saniye gerisinde kal─▒yor d2 . Birini Date di─čeriyle ayn─▒ yapman─▒n bir yolu , setTime y├Ântemi ├ža─č─▒rmakt─▒r , ancak bu Date s─▒n─▒fa ├Âzg├╝d├╝r . Hatal─▒ olmaktan memnuniyet duyar─▒m, ancak bu soruna kur┼čun ge├žirmez genel bir ├ž├Âz├╝m oldu─čunu sanm─▒yorum!

Ben ancak apa├ž─▒k bir kopyalaman─▒z gerekmektedir etti─či varsay─▒larak ├Âd├╝n sona erdi kopyalama genel derine uygulamak zorunda kal─▒nca Object , Array , Date , String , Number , veya Boolean . Son 3 tip de─či┼čmez, bu y├╝zden s─▒─č bir kopya ├ž─▒karabiliyorum ve onun i├žin endi┼če etmiyorum. Ayr─▒ca, listede yer alan Object veya Array ayn─▒ zamanda bu listedeki 6 basit tipten biri olabilece─čini de varsayd─▒m . Bu, a┼ča─č─▒daki gibi bir kodla ger├žekle┼čtirilebilir:

 function clone(obj) {
    var copy;

    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;

    // Handle Date
    if (obj instanceof Date) {
        copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
        copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = clone(obj[i]);
        }
        return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
        copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
        }
        return copy;
    }

    throw new Error("Unable to copy obj! Its type isn't supported.");
}
 

Yukar─▒daki i┼člev, nesnelerdeki ve dizilerdeki veriler bir a─ča├ž yap─▒s─▒ olu┼čturdu─ču s├╝rece bahsetti─čim 6 basit tip i├žin yeterli ┼čekilde ├žal─▒┼čacakt─▒r. Yani, nesnede ayn─▒ verilere birden fazla referans yoktur. ├ľrne─čin:

 // This would be cloneable:
var tree = {
    "left"  : { "left" : null, "right" : null, "data" : 3 },
    "right" : null,
    "data"  : 8
};

// This would kind-of work, but you would get 2 copies of the 
// inner node instead of 2 references to the same copy
var directedAcylicGraph = {
    "left"  : { "left" : null, "right" : null, "data" : 3 },
    "data"  : 8
};
directedAcyclicGraph["right"] = directedAcyclicGraph["left"];

// Cloning this would cause a stack overflow due to infinite recursion:
var cyclicGraph = {
    "left"  : { "left" : null, "right" : null, "data" : 3 },
    "data"  : 8
};
cyclicGraph["right"] = cyclicGraph;
 

Herhangi bir JavaScript nesnesini kullanamayacak, ancak att─▒─č─▒n─▒z herhangi bir ┼čey i├žin i┼če yarayaca─č─▒n─▒ varsaymad─▒─č─▒n─▒z s├╝rece bir├žok ama├ž i├žin yeterli olabilir.


1486







Date Nesnenizde s, i┼člevler, tan─▒ms─▒z veya Sonsuzluk kullanm─▒yorsan─▒z , ├žok basit bir astar JSON.parse(JSON.stringify(object)) :

 const a = {
  string: 'string',
  number: 123,
  bool: false,
  nul: null,
  date: new Date(),  // stringified
  undef: undefined,  // lost
  inf: Infinity,  // forced to 'null'
}
console.log(a);
console.log(typeof a.date);  // Date object
const clone = JSON.parse(JSON.stringify(a));
console.log(clone);
console.log(typeof clone.date);  // result of .toISOString() 

Bu, nesneler, diziler, dizeler, boolean'ler ve say─▒lar i├žeren her t├╝r nesne i├žin i┼če yarar.

Ayr─▒ca , bir i┼č├žiye veya bir i┼č├židen ileti g├Ânderirken kullan─▒lan taray─▒c─▒lar─▒n yap─▒land─▒r─▒lm─▒┼č klon algoritmas─▒ hakk─▒nda bu makaleye bak─▒n . Ayn─▒ zamanda derin klonlama i├žin bir i┼člev i├žerir.


907







JQuery ile ┼čunlar─▒ yapabilirsiniz s─▒─č kopya ile uzatmak :

 var copiedObject = jQuery.extend({}, originalObject)
 

m├╝teakip de─či┼čiklikler, copiedObject etkilemeyecektir originalObject ve bunun tersi de ge├žerlidir.

Veya derin bir kopya ├ž─▒karmak i├žin :

 var copiedObject = jQuery.extend(true, {}, originalObject)
 

764







ECMAScript 6'da , numaraland─▒r─▒labilir t├╝m ├Âzelliklerin de─čerlerini bir nesneden di─čerine kopyalayan Object.assign y├Ântemi vard─▒r . ├ľrne─čin:

 var x = {myProp: "value"};
var y = Object.assign({}, x); 
 

Ancak i├ž i├že ge├žmi┼č nesnelerin hala referans olarak kopyaland─▒─č─▒n─▒ unutmay─▒n.


639







MDN ba┼č─▒na :

  • S─▒─č kopya istiyorsan─▒z, Object.assign({}, a)
  • "Derin" kopya i├žin kullan─▒n JSON.parse(JSON.stringify(a))

Harici k├╝t├╝phanelere gerek yoktur, ancak ├Ânce taray─▒c─▒ uyumlulu─čunu kontrol etmeniz gerekir .


200







Pek ├žok cevap var, ancak hi├žbiri size kesin bir kopya vermeyen ama kayna─č─▒ yeni nesnenin prototipi olarak ayarlayan ECMAScript 5'ten Object.create'den bahsetmiyor .

Dolay─▒s─▒yla, bu sorunun cevab─▒ tam de─čil, tek sat─▒rl─▒k bir ├ž├Âz├╝m ve ├žok zarif. Ve 2 vaka i├žin en iyi sonucu verir:

  1. B├Âyle bir miras─▒n yararl─▒ oldu─ču yerlerde (hah!)
  2. Kaynak nesnenin de─či┼čtirilmedi─či yerde 2 nesne aras─▒ndaki ili┼čki sorun olmaz.

├ľrnek:

 var foo = { a : 1 };
var bar = Object.create(foo);
foo.a; // 1
bar.a; // 1
foo.a = 2;
bar.a; // 2 - prototype changed
bar.a = 3;
foo.a; // Still 2, since setting bar.a makes it an "own" property
 

Neden bu ├ž├Âz├╝m├╝ ├╝st├╝n buluyorum? Yerli, bu nedenle d├Âng├╝ yok, ├Âzyineleme yok. Ancak, eski taray─▒c─▒lar─▒n bir poli dolguna ihtiyac─▒ olacakt─▒r.


130







Javascript nesnesini bir kod sat─▒r─▒nda klonlaman─▒n zarif bir yolu

Bir Object.assign y├Ântem ECMAScript 2015 (ES6) standard─▒n─▒n bir par├žas─▒d─▒r ve tam olarak ihtiyac─▒n─▒z olan─▒ yapar.

 var clone = Object.assign({}, obj);
 

Object.assign () y├Ântemi, numaraland─▒r─▒labilir t├╝m ├Âzelliklerin de─čerlerini bir veya daha fazla kaynak nesneden bir hedef nesneye kopyalamak i├žin kullan─▒l─▒r.

Daha fazla oku...

Polyfill eski taray─▒c─▒lar─▒ desteklemek i├žin:

 if (!Object.assign) {
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        var keysArray = Object.keys(nextSource);
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}
 

121







─░nternette ├žo─ču ├ž├Âz├╝m├╝ olan birka├ž sorun var. Bu y├╝zden, kabul edilen cevab─▒n neden kabul edilmemesi gerekti─čini i├žeren bir takip yapmaya karar verdim.

ba┼člang─▒├ž ÔÇőÔÇődurumu

Javascript'i t├╝m ├žocuklar─▒ ve ├žocuklar─▒ ile birlikte derinlemesine kopyalamak istiyorum Object . Ben t├╝r normal bir geli┼čtiricinin oldu─čuma Ama benim Object sahiptir , normal properties , circular structures hatta nested objects .

├ľyleyse bir circular structure ve bir nested object ilk olu┼čtural─▒m .

 function Circ() {
    this.me = this;
}

function Nested(y) {
    this.y = y;
}
 

Her ┼čeyi bir Object isimle bir araya getirelim a .

 var a = {
    x: 'a',
    circ: new Circ(),
    nested: new Nested('a')
};
 

Daha sonra, a adland─▒r─▒lm─▒┼č bir de─či┼čkene kopyalay─▒p b onu mutasyona u─čratmak istiyoruz .

 var b = a;

b.x = 'b';
b.nested.y = 'b';
 

Burada ne oldu─čunu biliyorsun ├ž├╝nk├╝ bu harika soruya inmezdin bile.

 console.log(a, b);

a --> Object {
    x: "b",
    circ: Circ {
        me: Circ { ... }
    },
    nested: Nested {
        y: "b"
    }
}

b --> Object {
    x: "b",
    circ: Circ {
        me: Circ { ... }
    },
    nested: Nested {
        y: "b"
    }
}
 

┼×imdi bir ├ž├Âz├╝m bulal─▒m.

JSON

Denedim ilk deneme kullan─▒yordu JSON .

 var b = JSON.parse( JSON.stringify( a ) );

b.x = 'b';
b.nested.y = 'b';
 

Çok fazla zaman kaybetme, anlarsın TypeError: Converting circular structure to JSON .

├ľzyinelemeli kopya (kabul edilen "cevap")

Kabul edilen cevaba bir g├Âz atal─▒m.

 function cloneSO(obj) {
    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;

    // Handle Date
    if (obj instanceof Date) {
        var copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
        var copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = cloneSO(obj[i]);
        }
        return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
        var copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = cloneSO(obj[attr]);
        }
        return copy;
    }

    throw new Error("Unable to copy obj! Its type isn't supported.");
}
 

─░yi g├Âr├╝n├╝yor, ha? Nesnenin ├Âzyinelemeli bir kopyas─▒ ve di─čer t├╝rleri de ayn─▒ ┼čekilde ele al─▒yor Date , ancak bu bir gereklilik de─čildi.

 var b = cloneSO(a);

b.x = 'b';
b.nested.y = 'b';
 

├ľzyineleme ve circular structures birlikte iyi ├žal─▒┼čmaz ... RangeError: Maximum call stack size exceeded

yerel ├ž├Âz├╝m

─░┼č arkada┼č─▒mla tart─▒┼čt─▒ktan sonra, patronum bize ne oldu─čunu sordu ve bir miktar googling sonras─▒nda basit bir ├ž├Âz├╝m buldu . Buna denir Object.create .

 var b = Object.create(a);

b.x = 'b';
b.nested.y = 'b';
 

Bu ├ž├Âz├╝m bir s├╝re ├Ânce Javascript'e eklenmi┼č ve hatta tan─▒t─▒c─▒lar circular structure .

 console.log(a, b);

a --> Object {
    x: "a",
    circ: Circ {
        me: Circ { ... }
    },
    nested: Nested {
        y: "b"
    }
}

b --> Object {
    x: "b",
    circ: Circ {
        me: Circ { ... }
    },
    nested: Nested {
        y: "b"
    }
}
 

... ve g├Âr├╝yorsunuz, i├ž i├že ge├žmi┼č yap─▒yla ├žal─▒┼čmad─▒.

do─čal ├ž├Âz├╝m i├žin polyfill

Object.create Eski taray─▒c─▒da IE 8 gibi bir ├žoklu dolum var. Mozilla taraf─▒ndan ├Ânerilen bir ┼čey ve tabii ki m├╝kemmel de─čil ve yerel ├ž├Âz├╝mle ayn─▒ soruna yol a├ž─▒yor .

 function F() {};
function clonePF(o) {
    F.prototype = o;
    return new F();
}

var b = clonePF(a);

b.x = 'b';
b.nested.y = 'b';
 

F Kapsam d─▒┼č─▒na koydum , b├Âylece instanceof bize neler anlatt─▒─č─▒na bir g├Âz atabiliriz .

 console.log(a, b);

a --> Object {
    x: "a",
    circ: Circ {
        me: Circ { ... }
    },
    nested: Nested {
        y: "b"
    }
}

b --> F {
    x: "b",
    circ: Circ {
        me: Circ { ... }
    },
    nested: Nested {
        y: "b"
    }
}

console.log(typeof a, typeof b);

a --> object
b --> object

console.log(a instanceof Object, b instanceof Object);

a --> true
b --> true

console.log(a instanceof F, b instanceof F);

a --> false
b --> true
 

Yerel ├ž├Âz├╝m ile ayn─▒ sorun , ancak biraz daha k├Ât├╝ ├ž─▒kt─▒.

daha iyi (ama m├╝kemmel de─čil) ├ž├Âz├╝m

Etraf─▒nda kaz─▒ yaparken, benzer bir soru buldum ( Javascript'te, derin bir kopya ├ž─▒kar─▒rken, bu ├Âzelli─čin "bu" olmas─▒ nedeniyle bir ├ževrimi nas─▒l ├Ânleyebilirim? ), Ancak bunun daha iyi bir ├ž├Âz├╝mle.

 function cloneDR(o) {
    const gdcc = "__getDeepCircularCopy__";
    if (o !== Object(o)) {
        return o; // primitive value
    }

    var set = gdcc in o,
        cache = o[gdcc],
        result;
    if (set && typeof cache == "function") {
        return cache();
    }
    // else
    o[gdcc] = function() { return result; }; // overwrite
    if (o instanceof Array) {
        result = [];
        for (var i=0; i<o.length; i++) {
            result[i] = cloneDR(o[i]);
        }
    } else {
        result = {};
        for (var prop in o)
            if (prop != gdcc)
                result[prop] = cloneDR(o[prop]);
            else if (set)
                result[prop] = cloneDR(cache);
    }
    if (set) {
        o[gdcc] = cache; // reset
    } else {
        delete o[gdcc]; // unset again
    }
    return result;
}

var b = cloneDR(a);

b.x = 'b';
b.nested.y = 'b';
 

Ve ├ž─▒kt─▒s─▒na bir g├Âz atal─▒m ...

 console.log(a, b);

a --> Object {
    x: "a",
    circ: Object {
        me: Object { ... }
    },
    nested: Object {
        y: "a"
    }
}

b --> Object {
    x: "b",
    circ: Object {
        me: Object { ... }
    },
    nested: Object {
        y: "b"
    }
}

console.log(typeof a, typeof b);

a --> object
b --> object

console.log(a instanceof Object, b instanceof Object);

a --> true
b --> true

console.log(a instanceof F, b instanceof F);

a --> false
b --> false
 

Gereksinim e┼čle┼čti, ancak de─či┼čtirme dahil baz─▒ k├╝├ž├╝k sorunlar hala var instance i├žinde nested ve circ hi├ž Object .

Bir yapra─č─▒ payla┼čan a─ča├žlar─▒n yap─▒s─▒ kopyalanmayacak, iki ba─č─▒ms─▒z yaprak olacak:

         [Object]                     [Object]
         /    \                       /    \
        /      \                     /      \
      |/_      _\|                 |/_      _\|  
  [Object]    [Object]   ===>  [Object]    [Object]
       \        /                 |           |
        \      /                  |           |
        _\|  |/_                 \|/         \|/
        [Object]               [Object]    [Object]
 

Sonu├ž

├ľzyineleme ve ├Ânbellek kullanan son ├ž├Âz├╝m, en iyisi olmayabilir, ancak nesnenin ger├žek bir kopyas─▒d─▒r. ├çok basit kollar─▒ properties , circular structures ve nested object , ama olacak bunlar─▒n ├Ârne─čine kadar kar─▒┼č─▒kl─▒k klonlama s─▒ras─▒nda.

jsfiddle


82







S─▒─č bir kopya ile tamamsan─▒z, underscore.js k├╝t├╝phanesinin bir klonlama y├Ântemi vard─▒r.

 y = _.clone(x);
 

ya da gibi uzatabilirsiniz

 copiedObject = _.extend({},originalObject);
 

76


2012-06-13





Tamam, a┼ča─č─▒da bu nesneye sahip oldu─čunuzu ve onu kopyalamak istedi─činizi d├╝┼č├╝n├╝n:

 let obj = {a:1, b:2, c:3}; //ES6
 

veya

 var obj = {a:1, b:2, c:3}; //ES5
 

Cevap genel olarak hangi depeneds oldu─ču ECMAscript sen kullan─▒larak ES6+ , sadece kullanabilirsiniz Object.assign klon yapmak:

 let cloned = Object.assign({}, obj); //new {a:1, b:2, c:3};
 

ya da b├Âyle bir yay─▒lma i┼čleci kullanarak:

 let cloned = {...obj}; //new {a:1, b:2, c:3};
 

Ancak, kullan─▒yorsan─▒z ES5 , birka├ž y├Ântem kullanabilirsiniz, ancak JSON.stringify , sadece kopyalamak i├žin b├╝y├╝k bir veri y─▒─č─▒n─▒ i├žin kullanmad─▒─č─▒n─▒zdan emin olun, ancak ├žo─ču durumda bunun tek bir kullan─▒┼čl─▒ yolu olabilir:

 let cloned = JSON.parse(JSON.stringify(obj)); 
//new {a:1, b:2, c:3};, can be handy, but avoid using on big chunk of data over and over
 

52







├ľzellikle karars─▒z ├ž├Âz├╝mlerden biri, ├╝ye y├Ântemlere sahip olmayan nesnelerin derin kopyalar─▒n─▒ almak i├žin JSON kodlamas─▒n─▒ kullanmakt─▒r. Metodoloji, JSON'un hedef nesnenizi kodlamas─▒d─▒r, daha sonra kodu ├ž├Âzerek, arad─▒─č─▒n─▒z kopyay─▒ al─▒rs─▒n─▒z. ─░htiyac─▒n─▒z kadar kopya ├ž─▒karmak istedi─činiz kadar kod ├ž├Âzebilirsiniz.

Elbette, fonksiyonlar JSON'a ait de─čildir, bu nedenle bu sadece ├╝ye metotlar─▒ olmayan nesneler i├žin ge├žerlidir.

Bu metodoloji benim kullan─▒m durumum i├žin m├╝kemmeldi, ├ž├╝nk├╝ JSON blob'lar─▒n─▒ bir anahtar-de─čer deposunda sakl─▒yorum ve bir JavaScript API'sinde nesneler olarak g├Âr├╝nd├╝klerinde, her bir nesne asl─▒nda nesnenin orijinal durumunun bir kopyas─▒n─▒ i├žeriyor. Arayan maruz kalan nesneyi mutasyona u─čratt─▒ktan sonra deltay─▒ hesaplayabilir.

 var object1 = {key:"value"};
var object2 = object1;

object2 = JSON.stringify(object1);
object2 = JSON.parse(object2);

object2.key = "a change";
console.log(object1);// returns value
 

38







Ba┼čvuru olmadan bir nesneyi kopyalamak i├žin spread ├Âzelli─čini kullanabilirsiniz . Ancak dikkatli olun (yorumlara bak─▒n), 'kopya' sadece en d├╝┼č├╝k nesne / dizi seviyesindedir. ─░├ž i├že ge├žmi┼č ├Âzellikler hala referanst─▒r!


Komple klon:

 let x = {a: 'value1'}
let x2 = {...x}

// => mutate without references:

x2.a = 'value2'
console.log(x.a)    // => 'value1'
 

─░kinci seviyede referanslarla klonlama:

 const y = {a: {b: 'value3'}}
const y2 = {...y}

// => nested object is still a references:

y2.a.b = 'value4'
console.log(y.a.b)    // => 'value4'
 

JavaScript asl─▒nda do─čal olarak klonlar─▒ desteklemiyor. Bir yard─▒mc─▒ i┼člev kullan─▒n. ├ľrne─čin Ramda:

http://ramdajs.com/docs/#clone


34







AngularJS kullananlar i├žin, bu k├╝t├╝phanedeki nesnelerin klonlanmas─▒ veya geni┼čletilmesi i├žin do─črudan bir y├Ântem de vard─▒r.

 var destination = angular.copy(source);
 

veya

 angular.copy(source, destination);
 

Angular.copy belgelerinde daha fazlas─▒ ...


25







A.Levy'nin cevab─▒ neredeyse tamamland─▒, i┼čte benim k├╝├ž├╝k katk─▒m: ├Âzyinelemeli referanslar─▒ nas─▒l ele alaca─č─▒m─▒z─▒n bir yolu var, bu sat─▒r─▒ g├Âr├╝n

if(this[attr]==this) copy[attr] = copy;

Nesne XML DOM ├Â─česi ise, bunun yerine cloneNode kullanmal─▒y─▒z

if(this.cloneNode) return this.cloneNode(true);

A.Levy'in ayr─▒nt─▒l─▒ ├žal─▒┼čmas─▒ndan ve Calvin'in prototip yakla┼č─▒m─▒ndan ilham alarak, ┼ču ├ž├Âz├╝m├╝ ├Âneriyorum:

 Object.prototype.clone = function() {
  if(this.cloneNode) return this.cloneNode(true);
  var copy = this instanceof Array ? [] : {};
  for(var attr in this) {
    if(typeof this[attr] == "function" || this[attr]==null || !this[attr].clone)
      copy[attr] = this[attr];
    else if(this[attr]==this) copy[attr] = copy;
    else copy[attr] = this[attr].clone();
  }
  return copy;
}

Date.prototype.clone = function() {
  var copy = new Date();
  copy.setTime(this.getTime());
  return copy;
}

Number.prototype.clone = 
Boolean.prototype.clone =
String.prototype.clone = function() {
  return this;
}
 

Ayr─▒ca cevaplarda Andy Burke'├╝n notuna bak─▒n─▒z.


22







─░┼čte kullanabilece─činiz bir fonksiyon.

 function clone(obj) {
    if(obj == null || typeof(obj) != 'object')
        return obj;    
    var temp = new obj.constructor(); 
    for(var key in obj)
        temp[key] = clone(obj[key]);    
    return temp;
}
 

19







Bu makaleden: Javascript'teki diziler ve nesneler Brian Huisman taraf─▒ndan nas─▒l kopyalan─▒r :

 Object.prototype.clone = function() {
  var newObj = (this instanceof Array) ? [] : {};
  for (var i in this) {
    if (i == 'clone') continue;
    if (this[i] && typeof this[i] == "object") {
      newObj[i] = this[i].clone();
    } else newObj[i] = this[i]
  } return newObj;
};
 

19







ES-6'da Object.assign (...) komutunu kullanabilirsiniz. ├ľr:

 let obj = {person: 'Thor Odinson'};
let clone = Object.assign({}, obj);
 

─░yi bir referans burada: https://googlechrome.github.io/samples/object-assign-es6/


18







ECMAScript 2018ÔÇÖde

 let objClone = { ...obj };
 

Unutmay─▒n i├ž i├že nesneleri hala kopyaland─▒─č─▒ bir referans olarak.


18







Tek bir kod sat─▒r─▒ kullanarak bir nesneyi klonlayabilir ve bir ├Âncekinden gelen referanslar─▒ kald─▒rabilirsiniz. Basit├že yap─▒n:

 var obj1 = { text: 'moo1' };
var obj2 = Object.create(obj1); // Creates a new clone without references

obj2.text = 'moo2'; // Only updates obj2's text property

console.log(obj1, obj2); // Outputs: obj1: {text:'moo1'}, obj2: {text:'moo2'}
 

Object.create ├Âzelli─čini ┼ču anda desteklemeyen taray─▒c─▒lar / motorlar i├žin bu polyfill'i kullanabilirsiniz:

 // Polyfill Object.create if it does not exist
if (!Object.create) {
    Object.create = function (o) {
        var F = function () {};
        F.prototype = o;
        return new F();
    };
}
 

13







Eski bir soruya yeni cevap! ECMAScript 2016 (ES6) Spread S├Âzdizimi ile kullanma zevkiniz varsa , bu kolayd─▒r.

 keepMeTheSame = {first: "Me!", second: "You!"};
cloned = {...keepMeTheSame}
 

Bu, bir nesnenin s─▒─č bir kopyas─▒ i├žin temiz bir y├Ântem sa─člar. Derin bir kopyas─▒n─▒ ├ž─▒karmak, her yinelemeli i├ž i├že nesneyle her de─čerin yeni bir kopyas─▒n─▒ almak anlam─▒na gelir, yukar─▒daki daha a─č─▒r ├ž├Âz├╝mler gerektirir.

JavaScript geli┼čmeye devam ediyor.


13







Basit nesneleri klonlamakla ilgileniyor:

JSON.parse(JSON.stringify(json_original));

Kaynak: JavaScript nesnesini referans olarak DE─×─░L yeni de─či┼čkene nas─▒l kopyalar─▒m?


12







 let clone = Object.assign( Object.create( Object.getPrototypeOf(obj)), obj)
 

ES6 ├ž├Âz├╝m├╝, yaln─▒zca bir ├Âzellik nesnesini de─čil, bir s─▒n─▒f ├Ârne─čini klonlamak (s─▒─č) istiyorsan─▒z .


11







Lodash'─▒ Kullanma:

 var y = _.clone(x, true);
 

10







Bence basit ve ├žal─▒┼čan bir cevap var. Derin kopyada iki kayg─▒ var:

  1. ├ľzellikleri birbirinden ba─č─▒ms─▒z tutun.
  2. Ve klonlanan nesnede y├Ântemleri canl─▒ tutun.

Bu nedenle, basit bir ├ž├Âz├╝m├╝n ├Ânce seri hale getirmek ve seri hale getirmek ve ard─▒ndan da i┼člevleri kopyalamak i├žin bir g├Ârev yapmak oldu─čunu d├╝┼č├╝n├╝yorum.

 let deepCloned = JSON.parse(JSON.stringify(source));
let merged = Object.assign({}, source);
Object.assign(merged, deepCloned);
 

Bu sorunun bir├žok cevab─▒ olmas─▒na ra─čmen, umar─▒m bu da yard─▒mc─▒ olur.


9







Derin bir kopyalay─▒p klonlamak i├žin, JSON.stringify, ard─▒ndan nesneyi JSON.parse:

 obj = { a: 0 , b: { c: 0}};
let deepClone = JSON.parse(JSON.stringify(obj));
obj.a = 5;
obj.b.c = 5;
console.log(JSON.stringify(deepClone)); // { a: 0, b: { c: 0}}
 

8







Sadece Object.create bu yaz─▒daki t├╝m ├ž├Âz├╝mleri eklemek istedim , bunun nodejs ile istenen ┼čekilde ├žal─▒┼čmad─▒─č─▒n─▒.

FirefoxÔÇÖun sonucu

 var a = {"test":"test"};
var b = Object.create(a);
console.log(b);┬┤
 

oldu─ču

{test:"test"} .

Nodejs i├žinde

 {}
 

6







Bu, fonksiyonlar─▒n ve ├žoklu / d├Âng├╝sel referanslar─▒n klonlanmas─▒n─▒ i┼člemek i├žin ayr─▒ca A. Levy'nin kodunun bir uyarlamas─▒d─▒r - bunun anlam─▒, klonlanan a─ča├žtaki iki ├Âzellik ayn─▒ nesnenin referanslar─▒ysa, klonlanan nesne a─čac─▒n─▒n bunlara sahip olmas─▒d─▒r. ├Âzellikleri ba┼čvurulan nesnenin bir ve ayn─▒ klonunu g├Âsterir. Bu ayn─▒ zamanda, e─čer kullan─▒lmazsa, sonsuz bir d├Âng├╝ye yol a├žan d├Âng├╝sel ba─č─▒ml─▒l─▒klar durumunu da ├ž├Âzer. Algoritman─▒n karma┼č─▒kl─▒─č─▒ O (n) 'dir.

 function clone(obj){
    var clonedObjectsArray = [];
    var originalObjectsArray = []; //used to remove the unique ids when finished
    var next_objid = 0;

    function objectId(obj) {
        if (obj == null) return null;
        if (obj.__obj_id == undefined){
            obj.__obj_id = next_objid++;
            originalObjectsArray[obj.__obj_id] = obj;
        }
        return obj.__obj_id;
    }

    function cloneRecursive(obj) {
        if (null == obj || typeof obj == "string" || typeof obj == "number" || typeof obj == "boolean") return obj;

        // Handle Date
        if (obj instanceof Date) {
            var copy = new Date();
            copy.setTime(obj.getTime());
            return copy;
        }

        // Handle Array
        if (obj instanceof Array) {
            var copy = [];
            for (var i = 0; i < obj.length; ++i) {
                copy[i] = cloneRecursive(obj[i]);
            }
            return copy;
        }

        // Handle Object
        if (obj instanceof Object) {
            if (clonedObjectsArray[objectId(obj)] != undefined)
                return clonedObjectsArray[objectId(obj)];

            var copy;
            if (obj instanceof Function)//Handle Function
                copy = function(){return obj.apply(this, arguments);};
            else
                copy = {};

            clonedObjectsArray[objectId(obj)] = copy;

            for (var attr in obj)
                if (attr != "__obj_id" && obj.hasOwnProperty(attr))
                    copy[attr] = cloneRecursive(obj[attr]);                 

            return copy;
        }       


        throw new Error("Unable to copy obj! Its type isn't supported.");
    }
    var cloneObj = cloneRecursive(obj);



    //remove the unique ids
    for (var i = 0; i < originalObjectsArray.length; i++)
    {
        delete originalObjectsArray[i].__obj_id;
    };

    return cloneObj;
}
 

Baz─▒ h─▒zl─▒ testler

 var auxobj = {
    prop1 : "prop1 aux val", 
    prop2 : ["prop2 item1", "prop2 item2"]
    };

var obj = new Object();
obj.prop1 = "prop1_value";
obj.prop2 = [auxobj, auxobj, "some extra val", undefined];
obj.nr = 3465;
obj.bool = true;

obj.f1 = function (){
    this.prop1 = "prop1 val changed by f1";
};

objclone = clone(obj);

//some tests i've made
console.log("test number, boolean and string cloning: " + (objclone.prop1 == obj.prop1 && objclone.nr == obj.nr && objclone.bool == obj.bool));

objclone.f1();
console.log("test function cloning 1: " + (objclone.prop1 == 'prop1 val changed by f1'));
objclone.f1.prop = 'some prop';
console.log("test function cloning 2: " + (obj.f1.prop == undefined));

objclone.prop2[0].prop1 = "prop1 aux val NEW";
console.log("test multiple references cloning 1: " + (objclone.prop2[1].prop1 == objclone.prop2[0].prop1));
console.log("test multiple references cloning 2: " + (objclone.prop2[1].prop1 != obj.prop2[0].prop1));
 

6







 function clone(src, deep) {

    var toString = Object.prototype.toString;
    if(!src && typeof src != "object"){
        //any non-object ( Boolean, String, Number ), null, undefined, NaN
        return src;
    }

    //Honor native/custom clone methods
    if(src.clone && toString.call(src.clone) == "[object Function]"){
        return src.clone(deep);
    }

    //DOM Elements
    if(src.nodeType && toString.call(src.cloneNode) == "[object Function]"){
        return src.cloneNode(deep);
    }

    //Date
    if(toString.call(src) == "[object Date]"){
        return new Date(src.getTime());
    }

    //RegExp
    if(toString.call(src) == "[object RegExp]"){
        return new RegExp(src);
    }

    //Function
    if(toString.call(src) == "[object Function]"){
        //Wrap in another method to make sure == is not true;
        //Note: Huge performance issue due to closures, comment this :)
        return (function(){
            src.apply(this, arguments);
        });

    }

    var ret, index;
    //Array
    if(toString.call(src) == "[object Array]"){
        //[].slice(0) would soft clone
        ret = src.slice();
        if(deep){
            index = ret.length;
            while(index--){
                ret[index] = clone(ret[index], true);
            }
        }
    }
    //Object
    else {
        ret = src.constructor ? new src.constructor() : {};
        for (var prop in src) {
            ret[prop] = deep
                ? clone(src[prop], true)
                : src[prop];
        }
    }

    return ret;
};
 

6







Yana mindeavor nesnesi klonlanan 'de─či┼čmez in┼ča' nesne oldu─čunu ifade eden bir ├ž├Âzelti, basit├že olabilir olu┼čturmak nesnesinin bir ├Ârne─čini klonlama daha nesne birden ├žok kez yerine:

 function createMyObject()
{
    var myObject =
    {
        ...
    };
    return myObject;
}

var myObjectInstance1 = createMyObject();
var myObjectInstance2 = createMyObject();
 

6







Kendi uygulamam─▒ yazd─▒m. Daha iyi bir ├ž├Âz├╝m say─▒ld─▒─č─▒ndan emin de─čil:

 /*
    a function for deep cloning objects that contains other nested objects and circular structures.
    objects are stored in a 3D array, according to their length (number of properties) and their depth in the original object.
                                    index (z)
                                         |
                                         |
                                         |
                                         |
                                         |
                                         |                      depth (x)
                                         |_ _ _ _ _ _ _ _ _ _ _ _
                                        /_/_/_/_/_/_/_/_/_/
                                       /_/_/_/_/_/_/_/_/_/
                                      /_/_/_/_/_/_/...../
                                     /................./
                                    /.....            /
                                   /                 /
                                  /------------------
            object length (y)    /
*/
 

Uygulama a┼ča─č─▒dad─▒r:

 function deepClone(obj) {
    var depth = -1;
    var arr = [];
    return clone(obj, arr, depth);
}

/**
 *
 * @param obj source object
 * @param arr 3D array to store the references to objects
 * @param depth depth of the current object relative to the passed 'obj'
 * @returns {*}
 */
function clone(obj, arr, depth){
    if (typeof obj !== "object") {
        return obj;
    }

    var length = Object.keys(obj).length; // native method to get the number of properties in 'obj'

    var result = Object.create(Object.getPrototypeOf(obj)); // inherit the prototype of the original object
    if(result instanceof Array){
        result.length = length;
    }

    depth++; // depth is increased because we entered an object here

    arr[depth] = []; // this is the x-axis, each index here is the depth
    arr[depth][length] = []; // this is the y-axis, each index is the length of the object (aka number of props)
    // start the depth at current and go down, cyclic structures won't form on depths more than the current one
    for(var x = depth; x >= 0; x--){
        // loop only if the array at this depth and length already have elements
        if(arr[x][length]){
            for(var index = 0; index < arr[x][length].length; index++){
                if(obj === arr[x][length][index]){
                    return obj;
                }
            }
        }
    }

    arr[depth][length].push(obj); // store the object in the array at the current depth and length
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) result[prop] = clone(obj[prop], arr, depth);
    }

    return result;
}
 

6