Bir nesneyi JavaScript'te derin klonlaman─▒n en etkili yolu nedir?


Al─▒nan cevaba git


Bir JavaScript nesnesini klonlaman─▒n en etkili yolu nedir? obj = eval(uneval(o)); Kullan─▒ld─▒─č─▒n─▒ g├Ârd├╝m , ancak bu standart de─čil ve yaln─▒zca Firefox taraf─▒ndan destekleniyor .

Gibi ┼čeyler yapt─▒m obj = JSON.parse(JSON.stringify(o)); ama verimlili─či sorgulad─▒m.

Ayr─▒ca ├že┼čitli kusurlar─▒ olan ├Âzyinelemeli kopyalama i┼člevlerini g├Ârd├╝m.
Kanonik bir ├ž├Âz├╝m olmad─▒─č─▒na ┼ča┼č─▒rd─▒m.


5181









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






Yerli derin klonlama

Buna "yap─▒land─▒r─▒lm─▒┼č klonlama" denir, D├╝─č├╝m 11 ve sonras─▒nda deneysel olarak ├žal─▒┼č─▒r ve umar─▒m taray─▒c─▒lara iner. Daha fazla ayr─▒nt─▒ i├žin bu cevaba bak─▒n─▒z.

Veri kayb─▒yla h─▒zl─▒ klonlama - JSON.parse / stringify

E─čer kullanm─▒yorsan─▒z Date ler, fonksiyonlar, undefined , Infinity senin nesnenin i├žinde, regexpleri, Haritalar, K├╝meler, lekeler, filelists, ImageDatas, seyrek Diziler, Yaz─▒lan Diziler veya di─čer karma┼č─▒k t├╝rleri, derin klon ├žok basit bir liner bir nesnedir:

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'
  re: /.*/,  // lost
}
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() 

Kriterler i├žin Corban'─▒n cevab─▒na bak─▒n─▒z .

Bir k├╝t├╝phane kullanarak g├╝venilir klonlama

Nesneleri klonlamak ├Ânemsiz olmad─▒─č─▒ndan (karma┼č─▒k t├╝rler, dairesel referanslar, i┼člev vb.), ├ço─ču b├╝y├╝k kitapl─▒k nesneleri klonlamak i├žin i┼člev sa─člar. Tekerle─či yeniden icat etmeyin - zaten bir k├╝t├╝phane kullan─▒yorsan─▒z, nesne klonlama i┼člevi olup olmad─▒─č─▒n─▒ kontrol edin. ├ľrne─čin,

ES6

Tamamlanmas─▒ i├žin, ES6'n─▒n iki s─▒─č kopyalama mekanizmas─▒ sundu─čunu unutmay─▒n: Object.assign() ve yay─▒lma operat├Âr├╝ .


4450







Bu kriteri g├Âz at─▒n : http://jsben.ch/#/bWfk9

H─▒z─▒n temel bir endi┼če oldu─ču ├Ânceki testlerimde buldum

 JSON.parse(JSON.stringify(obj))
 

Bir nesneyi derin klonlaman─▒n en yava┼č yolu olmak ( bayrak% 10-20 ile do─čru olarak ayarlanm─▒┼č olan jQuery.extend'den daha yava┼č deep ).

deep Bayrak false (s─▒─č klon) olarak ayarland─▒─č─▒nda jQuery.extend olduk├ža h─▒zl─▒d─▒r . Bu, iyi bir se├ženektir, ├ž├╝nk├╝ tip do─črulama i├žin fazladan bir mant─▒k i├žermekte ve tan─▒ms─▒z ├Âzellikler ├╝zerine kopyalanmamakta, ancak bu sizi biraz yava┼člatmaktad─▒r.

Klonlamaya ├žal─▒┼čt─▒─č─▒n─▒z veya i├ž i├že ge├žmi┼č dizileri ├Ânleyebilece─činiz nesnelerin yap─▒s─▒n─▒ biliyorsan─▒z, for (var i in obj) hasOwnProperty ├Â─česini kontrol ederken nesnenizi klonlamak i├žin basit bir d├Âng├╝ yazabilirsiniz ve jQuery'den ├žok daha h─▒zl─▒ olacakt─▒r.

Son olarak, bilinen bir nesne yap─▒s─▒n─▒ s─▒cak bir d├Âng├╝de klonlamaya ├žal─▒┼č─▒yorsan─▒z, klonlama prosed├╝r├╝n├╝ basit├že astarlayarak ve nesneyi elle olu┼čturarak ├çOK DAHA FAZLA PERFORMANS alabilirsiniz.

JavaScript izleme motorlar─▒ for..in d├Âng├╝leri optimize etmek ve hasOwnProperty'i kontrol etmek i├žin emmek de sizi yava┼člat─▒r. H─▒z─▒n mutlak olmas─▒ gerekti─činde manuel klonlama gerekir.

 var clonedObject = {
  knownProp: obj.knownProp,
  ..
}
 

Kullanarak sak─▒n─▒n JSON.parse(JSON.stringify(obj)) ├╝zerinde y├Ântemini Date nesneleri - JSON.stringify(new Date()) ISO bi├žiminde tarih, bir dize temsilini d├Ând├╝r├╝r JSON.parse() vermez bir geri d├Ân├╝┼čt├╝rme Date nesne. Daha fazla ayr─▒nt─▒ i├žin bu cevaba bak─▒n─▒z .

Ek olarak, l├╝tfen Chrome 65'te en az─▒ndan yerel klonlaman─▒n kullanman─▒n bir yolu olmad─▒─č─▒n─▒ unutmay─▒n. G├Âre bu JSPerf , yeni bir fonksiyon olu┼čturarak yerli klonlama ger├žekle┼čtiren neredeyse oldu─čunu 800x yava┼č inan─▒lmaz derecede h─▒zl─▒ b├╝t├╝n y├Ân├╝yle yoludur JSON.stringify kullanmaktan daha.

ES6 G├╝ncellemesi

Javascript ES6 kullan─▒yorsan─▒z, klonlama veya s─▒─č kopyalama i├žin bu yerel y├Ântemi deneyin.

 Object.assign({}, obj);
 

2211







Yaln─▒zca de─či┼čkenler oldu─čunu ve nesnenizdeki hi├žbir i┼člevi olmad─▒─č─▒n─▒ varsayarak, yaln─▒zca ┼čunu kullanabilirsiniz:

 var newObject = JSON.parse(JSON.stringify(oldObject));
 

458







Yap─▒sal Klonlama

HTML standard─▒, derin nesneler klonlar─▒ olu┼čturabilen dahili bir yap─▒land─▒r─▒lm─▒┼č klonlama / serile┼čtirme algoritmas─▒ i├žerir. Hala baz─▒ yerle┼čik t├╝rlerle s─▒n─▒rl─▒d─▒r, ancak JSON taraf─▒ndan desteklenen birka├ž t├╝r├╝n yan─▒ s─▒ra, Tarihler, RegExps, Haritalar, K├╝meler, Blob'lar, Dosya Listeleri, ImageDatas, seyrek Diziler, Yaz─▒l─▒ Diziler ve muhtemelen gelecekte daha da fazlas─▒n─▒ destekler . Ayr─▒ca klonlanan verilerdeki referanslar─▒ korur ve JSON i├žin hatalara neden olacak d├Âng├╝sel ve ├Âzyinelemeli yap─▒lar─▒ desteklemesini sa─člar.

Node.js Deste─či: Deneysel ?

v8 (D├╝─č├╝m 11 itibariyle) ┼ču anda node.js mod├╝l do─črudan yap─▒land─▒r─▒lm─▒┼č seri API ortaya ├ž─▒kar─▒r , ancak bu i┼člev hala "deneysel" ve gelecekteki s├╝r├╝mlerinde de─či┼čiklik veya kald─▒rma tabi olarak i┼čaretlenir. Uyumlu bir s├╝r├╝m kullan─▒yorsan─▒z, bir nesneyi klonlamak:

 const v8 = require('v8');

const structuredClone = obj => {
  return v8.deserialize(v8.serialize(obj));
};
 

Taray─▒c─▒larda Do─črudan Destek: Belki de Sonunda? ?

Taray─▒c─▒lar ┼ču anda yap─▒land─▒r─▒lm─▒┼č klonlama algoritmas─▒ i├žin do─črudan bir aray├╝z sunmamaktad─▒r, ancak GitHub'da whatwg / html # 793'te global bir structuredClone() fonksiyon tart─▒┼č─▒lm─▒┼čt─▒r . Hali haz─▒rda ├Ânerildi─či gibi, ├žo─ču ama├ž i├žin kullanmak ┼ču kadar basit olacakt─▒r:https://github.com/whatwg/html/issues/793

 const clone = structuredClone(original);
 

Bu g├Ânderilmedi─či s├╝rece, taray─▒c─▒lar─▒n yap─▒land─▒r─▒lm─▒┼č klon uygulamalar─▒ yaln─▒zca dolayl─▒ olarak ortaya ├ž─▒kar.

Zaman Uyumsuz Ge├žici ├ç├Âz├╝m: Kullan─▒labilir. ?

Mevcut API'larla yap─▒land─▒r─▒lm─▒┼č bir klon olu┼čturman─▒n en d├╝┼č├╝k yolu, verileri bir MessageChannels ba─člant─▒ noktas─▒ndan kaydetmektir . Di─čer liman message ekli yap─▒land─▒r─▒lm─▒┼č bir klonu ile bir olay yayar .data . Ne yaz─▒k ki, bu olaylar─▒ dinlemek mutlaka e┼čzamans─▒zd─▒r ve e┼čzamanl─▒ alternatifler daha az pratiktir.

 class StructuredCloner {
  constructor() {
    this.pendingClones_ = new Map();
    this.nextKey_ = 0;

    const channel = new MessageChannel();
    this.inPort_ = channel.port1;
    this.outPort_ = channel.port2;

    this.outPort_.onmessage = ({data: {key, value}}) => {
      const resolve = this.pendingClones_.get(key);
      resolve(value);
      this.pendingClones_.delete(key);
    };
    this.outPort_.start();
  }

  cloneAsync(value) {
    return new Promise(resolve => {
      const key = this.nextKey_++;
      this.pendingClones_.set(key, resolve);
      this.inPort_.postMessage({key, value});
    });
  }
}

const structuredCloneAsync = window.structuredCloneAsync =
    StructuredCloner.prototype.cloneAsync.bind(new StructuredCloner);
 

├ľrnek Kullan─▒m:

 const main = async () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = await structuredCloneAsync(original);

  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));

  console.log("Assertions complete.");
};

main();
 

E┼čzamanl─▒ Ge├žici ├ç├Âz├╝mler: Awful! ?

E┼č zamanl─▒ olarak yap─▒land─▒r─▒lm─▒┼č klonlar olu┼čturmak i├žin iyi bir se├ženek yoktur. ─░┼čte bunun yerine birka├ž pratik sald─▒r─▒.

history.pushState() ve history.replaceState() her ikisi de ilk arg├╝manlar─▒n─▒n yap─▒land─▒r─▒lm─▒┼č bir klonunu yarat─▒r ve bu de─čeri atar history.state . Bunu, bunun gibi herhangi bir nesnenin yap─▒land─▒r─▒lm─▒┼č bir klonunu olu┼čturmak i├žin kullanabilirsiniz:

 const structuredClone = obj => {
  const oldState = history.state;
  history.replaceState(obj, null);
  const clonedObj = history.state;
  history.replaceState(oldState, null);
  return clonedObj;
};
 

├ľrnek Kullan─▒m:

 'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);
  
  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));
  
  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const oldState = history.state;
  history.replaceState(obj, null);
  const clonedObj = history.state;
  history.replaceState(oldState, null);
  return clonedObj;
};

main(); 

Senkron olsa da, bu son derece yava┼č olabilir. Taray─▒c─▒ ge├žmi┼čini manip├╝le etmekle ili┼čkili t├╝m ek masraflar─▒ i├žerir. Bu y├Ântemi tekrar tekrar ├ža─č─▒rmak, Chrome'un ge├žici olarak yan─▒t vermemesine neden olabilir.

Notification Yap─▒c─▒ ili┼čkili verilerin bir yap─▒land─▒r─▒lm─▒┼č klon yarat─▒r. Ayr─▒ca, kullan─▒c─▒ya bir taray─▒c─▒ bildirimi g├Âstermeye ├žal─▒┼č─▒r, ancak bildirim izni istemedi─činiz s├╝rece bu sessizce ba┼čar─▒s─▒z olur. Ba┼čka ama├žlarla izniniz olmas─▒ durumunda, olu┼čturdu─čumuz bildirimi derhal kapat─▒r─▒z.

 const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.onshow = n.close.bind(n);
  return n.data;
};
 

├ľrnek Kullan─▒m:

 'use strict';

const main = () => {
  const original = { date: new Date(), number: Math.random() };
  original.self = original;

  const clone = structuredClone(original);
  
  // They're different objects:
  console.assert(original !== clone);
  console.assert(original.date !== clone.date);

  // They're cyclical:
  console.assert(original.self === original);
  console.assert(clone.self === clone);

  // They contain equivalent values:
  console.assert(original.number === clone.number);
  console.assert(Number(original.date) === Number(clone.date));
  
  console.log("Assertions complete.");
};

const structuredClone = obj => {
  const n = new Notification('', {data: obj, silent: true});
  n.close();
  return n.data;
};

main(); 


362







Yerle┼čik bir tane olmasayd─▒, deneyebilirsin:

 function clone(obj) {
    if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
        return obj;

    if (obj instanceof Date)
        var temp = new obj.constructor(); //or new Date(obj);
    else
        var temp = obj.constructor();

    for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            obj['isActiveClone'] = null;
            temp[key] = clone(obj[key]);
            delete obj['isActiveClone'];
        }
    }
    return temp;
}
 

316







Bir nesneyi tek bir kod sat─▒r─▒nda klonlaman─▒n (derin klonlama de─čil) etkili 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;
    }
  });
}
 

154







Kod:

 // extends 'from' object with members from 'to'. If 'to' is null, a deep clone of 'from' is returned
function extend(from, to)
{
    if (from == null || typeof from != "object") return from;
    if (from.constructor != Object && from.constructor != Array) return from;
    if (from.constructor == Date || from.constructor == RegExp || from.constructor == Function ||
        from.constructor == String || from.constructor == Number || from.constructor == Boolean)
        return new from.constructor(from);

    to = to || new from.constructor();

    for (var name in from)
    {
        to[name] = typeof to[name] == "undefined" ? extend(from[name], null) : to[name];
    }

    return to;
}
 

├ľl├žek:

 var obj =
{
    date: new Date(),
    func: function(q) { return 1 + q; },
    num: 123,
    text: "asdasd",
    array: [1, "asd"],
    regex: new RegExp(/aaa/i),
    subobj:
    {
        num: 234,
        text: "asdsaD"
    }
}

var clone = extend(obj);
 

95







Kulland─▒─č─▒m ┼čey bu:

 function cloneObject(obj) {
    var clone = {};
    for(var i in obj) {
        if(typeof(obj[i])=="object" && obj[i] != null)
            clone[i] = cloneObject(obj[i]);
        else
            clone[i] = obj[i];
    }
    return clone;
}
 

93







Performansa g├Âre derin kopya: En iyiden en k├Ât├╝ye do─čru

  • Yeniden atama "=" (dize dizileri, say─▒ dizileri - yaln─▒zca)
  • Dilim (dize dizileri, say─▒ dizileri - yaln─▒zca)
  • Birle┼čtirme (dize dizileri, say─▒ dizileri - yaln─▒zca)
  • ├ľzel fonksiyon: for-loop veya ├Âzyinelemeli kopya
  • jQuery'nin fiyat─▒.
  • JSON.parse (string dizileri, say─▒ dizileri, nesne dizileri - yaln─▒zca)
  • Underscore.js '_ _clone (string dizileri, say─▒ dizileri - sadece)
  • Lo-Dash's _.cloneDeep

Bir dizi dizenin veya say─▒n─▒n derin kopyalanmas─▒ (bir seviye - referans i┼čaret├žisi yok):

Bir dizi say─▒lar ve dizgiler i├žerdi─činde - .slice (), .concat (), .splice () gibi i┼člevler, atama operat├Âr├╝ "=" ve Underscore.js'in klonlama i┼člevi; Dizinin elemanlar─▒n─▒n derin bir kopyas─▒n─▒ alaca─č─▒m.

Yeniden atama en h─▒zl─▒ performansa sahipse:

 var arr1 = ['a', 'b', 'c'];
var arr2 = arr1;
arr1 = ['a', 'b', 'c'];
 

Ve .slice () .concat (), http://jsperf.com/duplicate-array-slice-vs-concat/3 den daha iyi performans g├Âsterir http://jsperf.com/duplicate-array-slice-vs-concat/3

 var arr1 = ['a', 'b', 'c'];  // Becomes arr1 = ['a', 'b', 'c']
var arr2a = arr1.slice(0);   // Becomes arr2a = ['a', 'b', 'c'] - deep copy
var arr2b = arr1.concat();   // Becomes arr2b = ['a', 'b', 'c'] - deep copy
 

Bir nesne dizisini derin kopyalay─▒n (iki veya daha fazla seviye - referans i┼čaret├žileri):

 var arr1 = [{object:'a'}, {object:'b'}];
 

├ľzel bir i┼člev yaz─▒n ($ .extend () veya JSON.parse'den daha h─▒zl─▒ performansa sahip):

 function copy(o) {
   var out, v, key;
   out = Array.isArray(o) ? [] : {};
   for (key in o) {
       v = o[key];
       out[key] = (typeof v === "object" && v !== null) ? copy(v) : v;
   }
   return out;
}

copy(arr1);
 

├ť├ž├╝nc├╝ taraf yard─▒mc─▒ program i┼člevlerini kullan─▒n:

 $.extend(true, [], arr1); // Jquery Extend
JSON.parse(arr1);
_.cloneDeep(arr1); // Lo-dash
 

JQuery'nin $ .extend'inin daha iyi performans g├Âsterdi─či yerler:


77







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

Object.defineProperty( Object.prototype, "clone", {value: clone, enumerable: false});
 

63







Bunu olduk├ža iyi yapan bir k├╝t├╝phane (ÔÇťklonÔÇŁ olarak adland─▒r─▒l─▒r) var . Bildi─čim keyfi nesnelerin en ├Âzyinelemeli klonlamas─▒n─▒ / kopyalanmas─▒n─▒ sa─člar. Ayr─▒ca di─čer cevaplar─▒n kapsamad─▒─č─▒ dairesel referanslar─▒ da destekliyor.

Npm'de de bulabilirsiniz . Taray─▒c─▒ ve Node.js.

─░┼čte nas─▒l kullan─▒laca─č─▒na bir ├Ârnek:

Y├╝kleyin

 npm install clone
 

veya Ender ile paketleyin .

 ender build clone [...]
 

Kaynak kodunu manuel olarak da indirebilirsiniz.

Ard─▒ndan kaynak kodunuzda kullanabilirsiniz.

 var clone = require('clone');

var a = { foo: { bar: 'baz' } };  // inital value of a
var b = clone(a);                 // clone a -> b
a.foo.bar = 'foo';                // change a

console.log(a);                   // { foo: { bar: 'foo' } }
console.log(b);                   // { foo: { bar: 'baz' } }
 

(Feragatname: K├╝t├╝phanenin yazar─▒y─▒m.)


56







Bunun eski bir g├Ânderi oldu─čunu biliyorum, ama bunun bir araya gelen birisine yard─▒mc─▒ olabilece─čini d├╝┼č├╝nd├╝m.

Hi├žbir ┼čeye bir nesne atamazsan─▒z, bellekte referans kalmaz. Di─čer nesnelerle payla┼čmak istedi─činiz bir nesneyi yapmak i├žin, ┼č├Âyle bir fabrika olu┼čturman─▒z gerekir:

 var a = function(){
    return {
        father:'zacharias'
    };
},
b = a(),
c = a();
c.father = 'johndoe';
alert(b.father);
 

53







Cloning Bir Nesne JS'de her zaman bir kayg─▒lard─▒, ancak hepsi ES6'dan ├Ânceydi, a┼ča─č─▒da bir nesneyi JavaScript'e kopyalaman─▒n farkl─▒ yollar─▒n─▒ listeliyorum, a┼ča─č─▒daki Nesne'nin oldu─čunu ve bunun derin bir kopyas─▒n─▒n olmas─▒n─▒ istedi─činizi hayal edin:

 var obj = {a:1, b:2, c:3, d:4};
 

K├Âkeni de─či┼čtirmeden, bu nesneyi kopyalaman─▒n birka├ž yolu vard─▒r:

1) ES5 +, Kopyay─▒ sizin i├žin yapmak i├žin basit bir i┼člev kullanarak:

 function deepCopyObj(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    if (obj instanceof Date) {
        var copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }
    if (obj instanceof Array) {
        var copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = cloneSO(obj[i]);
        }
        return copy;
    }
    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 this object.");
}
 

2) ES5 +, JSON.parse ve JSON.stringify ├Â─česini kullanarak.

 var  deepCopyObj = JSON.parse(JSON.stringify(obj));
 

3) A├ž─▒salJ'ler:

 var  deepCopyObj = angular.copy(obj);
 

4) jQuery:

 var deepCopyObj = jQuery.extend(true, {}, obj);
 

5) Alt ├žizgi ve Loadash:

 var deepCopyObj = _.cloneDeep(obj); //latest version UndescoreJs makes shallow copy
 

Umar─▒m bu yard─▒mlar ...


53







Kullan─▒yorsan─▒z, Underscore.js k├╝t├╝phanesinde bir klonlama y├Ântemi vard─▒r.

 var newObject = _.clone(oldObject);
 

48







JavaScript'te derin kopya nesneler (en iyi ve en basit oldu─čunu d├╝┼č├╝n├╝yorum)

1. JSON.parse (JSON.stringify (object)) kullanarak;

 var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}
var newObj = JSON.parse(JSON.stringify(obj));
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } 
 

2. olu┼čturulan y├Ântemi kullanarak

 function cloneObject(obj) {
    var clone = {};
    for(var i in obj) {
        if(obj[i] != null &&  typeof(obj[i])=="object")
            clone[i] = cloneObject(obj[i]);
        else
            clone[i] = obj[i];
    }
    return clone;
}

var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}
var newObj = cloneObject(obj);
obj.b.c = 20;

console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } 
 

3. Lo-Dash'in _.cloneDeep ba─člant─▒s─▒ lodash'─▒ kullanma

 var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}

var newObj = _.cloneDeep(obj);
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 2 } } 
 

4. Object.assign () y├Ântemini kullanarak

 var obj = { 
  a: 1,
  b: 2
}

var newObj = _.clone(obj);
obj.b = 20;
console.log(obj); // { a: 1, b: 20 }
console.log(newObj); // { a: 1, b: 2 }  
 

AMA YANLI┼× YANLI┼×

 var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}

var newObj = Object.assign({}, obj);
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 20 } } --> WRONG
// Note: Properties on the prototype chain and non-enumerable properties cannot be copied.
 

5. Underscore.js _.clone ba─člant─▒s─▒n─▒ kullanma Underscore.js

 var obj = { 
  a: 1,
  b: 2
}

var newObj = _.clone(obj);
obj.b = 20;
console.log(obj); // { a: 1, b: 20 }
console.log(newObj); // { a: 1, b: 2 }  
 

AMA YANLI┼× YANLI┼×

 var obj = { 
  a: 1,
  b: { 
    c: 2
  }
}

var newObj = _.cloneDeep(obj);
obj.b.c = 20;
console.log(obj); // { a: 1, b: { c: 20 } }
console.log(newObj); // { a: 1, b: { c: 20 } } --> WRONG
// (Create a shallow-copied clone of the provided plain object. Any nested objects or arrays will be copied by reference, not duplicated.)
 

Ba┼čvuru orta.com

JSBEN.CH Performans Kar┼č─▒la┼čt─▒rma Oyun Park─▒ 1 ~ 3 http://jsben.ch/KVQLd
Performans JavaScript'te derin kopya nesneler


44







Burada, yap─▒c─▒ gerekli parametrelere sahip olsa bile ├žal─▒┼čan bir ConroyP yan─▒t─▒ s├╝r├╝m├╝:

 //If Object.create isn't already defined, we just do the simple shim,
//without the second argument, since that's all we need here
var object_create = Object.create;
if (typeof object_create !== 'function') {
    object_create = function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

function deepCopy(obj) {
    if(obj == null || typeof(obj) !== 'object'){
        return obj;
    }
    //make sure the returned object has the same prototype as the original
    var ret = object_create(obj.constructor.prototype);
    for(var key in obj){
        ret[key] = deepCopy(obj[key]);
    }
    return ret;
}
 

Bu fonksiyon basit kitapl─▒─č─▒mda da mevcuttur .

D├╝zenle:

─░┼čte daha sa─člam bir versiyon (Justin McCandless sayesinde bu art─▒k d├Âng├╝sel referanslar─▒ da destekliyor):

 /**
 * Deep copy an object (make copies of all its object properties, sub-properties, etc.)
 * An improved version of http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
 * that doesn't break if the constructor has required parameters
 * 
 * It also borrows some code from http://stackoverflow.com/a/11621004/560114
 */ 
function deepCopy(src, /* INTERNAL */ _visited, _copiesVisited) {
    if(src === null || typeof(src) !== 'object'){
        return src;
    }

    //Honor native/custom clone methods
    if(typeof src.clone == 'function'){
        return src.clone(true);
    }

    //Special cases:
    //Date
    if(src instanceof Date){
        return new Date(src.getTime());
    }
    //RegExp
    if(src instanceof RegExp){
        return new RegExp(src);
    }
    //DOM Element
    if(src.nodeType && typeof src.cloneNode == 'function'){
        return src.cloneNode(true);
    }

    // Initialize the visited objects arrays if needed.
    // This is used to detect cyclic references.
    if (_visited === undefined){
        _visited = [];
        _copiesVisited = [];
    }

    // Check if this object has already been visited
    var i, len = _visited.length;
    for (i = 0; i < len; i++) {
        // If so, get the copy we already made
        if (src === _visited[i]) {
            return _copiesVisited[i];
        }
    }

    //Array
    if (Object.prototype.toString.call(src) == '[object Array]') {
        //[].slice() by itself would soft clone
        var ret = src.slice();

        //add it to the visited array
        _visited.push(src);
        _copiesVisited.push(ret);

        var i = ret.length;
        while (i--) {
            ret[i] = deepCopy(ret[i], _visited, _copiesVisited);
        }
        return ret;
    }

    //If we've reached here, we have a regular object

    //make sure the returned object has the same prototype as the original
    var proto = (Object.getPrototypeOf ? Object.getPrototypeOf(src): src.__proto__);
    if (!proto) {
        proto = src.constructor.prototype; //this line would probably only be reached by very old browsers 
    }
    var dest = object_create(proto);

    //add this object to the visited array
    _visited.push(src);
    _copiesVisited.push(dest);

    for (var key in src) {
        //Note: this does NOT preserve ES5 property attributes like 'writable', 'enumerable', etc.
        //For an example of how this could be modified to do so, see the singleMixin() function
        dest[key] = deepCopy(src[key], _visited, _copiesVisited);
    }
    return dest;
}

//If Object.create isn't already defined, we just do the simple shim,
//without the second argument, since that's all we need here
var object_create = Object.create;
if (typeof object_create !== 'function') {
    object_create = function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
 

41







A┼ča─č─▒daki, ayn─▒ nesnenin iki ├Ârne─čini olu┼čturur. Onu buldum ve ┼ču anda kullan─▒yorum. Basit ve kullan─▒m─▒ kolayd─▒r.

 var objToCreate = JSON.parse(JSON.stringify(cloneThis));
 

31







Lodash g├╝zel bir _.cloneDeep (value) y├Ântemine sahiptir:

 var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
 

23







Crockford bu i┼člevi kullanmay─▒ ├Ânerir (ve ben tercih ederim):

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

var newObject = object(oldObject);
 

├ľzl├╝, beklendi─či gibi ├žal─▒┼č─▒yor ve bir k├╝t├╝phaneye ihtiyac─▒n─▒z yok.


D├ťZENLE:

Bu bir polyfill Object.create , yani bunu da kullanabilirsiniz.

 var newObject = Object.create(oldObject);
 

NOT: Bunlardan baz─▒lar─▒n─▒ kullan─▒rsan─▒z, kullanan baz─▒ yinelemeyle ilgili problemleriniz olabilir hasOwnProperty . ├ç├╝nk├╝, create miras alan yeni bir bo┼č nesne yarat oldObject . Ancak nesneleri klonlamak i├žin hala kullan─▒┼čl─▒ ve pratiktir.

├ľrnek i├žin e─čer oldObject.a = 5;

 newObject.a; // is 5
 

fakat:

 oldObject.hasOwnProperty(a); // is true
newObject.hasOwnProperty(a); // is false
 

22







 function clone(obj)
 { var clone = {};
   clone.prototype = obj.prototype;
   for (property in obj) clone[property] = obj[property];
   return clone;
 }
 

21







Tek kopya olan s─▒─č kopya ( ECMAScript 5. bask─▒ ):

 var origin = { foo : {} };
var copy = Object.keys(origin).reduce(function(c,k){c[k]=origin[k];return c;},{});

console.log(origin, copy);
console.log(origin == copy); // false
console.log(origin.foo == copy.foo); // true
 

Ve s─▒─č kopya bir liner ( ECMAScript 6th edition , 2015):

 var origin = { foo : {} };
var copy = Object.assign({}, origin);

console.log(origin, copy);
console.log(origin == copy); // false
console.log(origin.foo == copy.foo); // true
 

19







S─▒rf AngularJS'nin bahsetti─čini ve insanlar─▒n bilmek isteyebilece─čini d├╝┼č├╝nd├╝─č├╝m i├žin ...

angular.copy ayr─▒ca, derin nesnelere ve dizilere kopyalama y├Ântemi sunar.


17







Dizi benzeri nesneler i├žin hen├╝z ideal bir derin klon operat├Âr├╝ bulunmuyor. A┼ča─č─▒daki kodun g├Âsterdi─či gibi, John Resig'in jQuery klonlay─▒c─▒s─▒, say─▒sal olmayan ├Âzelliklere sahip olan dizileri dizisi olmayan nesnelere d├Ân├╝┼čt├╝r├╝r ve RegDwight'─▒n JSON klonlay─▒c─▒s─▒ say─▒sal olmayan ├Âzellikleri d├╝┼č├╝r├╝r. A┼ča─č─▒daki testler, ├žoklu taray─▒c─▒larda bu noktalar─▒ g├Âstermektedir:

 function jQueryClone(obj) {
   return jQuery.extend(true, {}, obj)
}

function JSONClone(obj) {
   return JSON.parse(JSON.stringify(obj))
}

var arrayLikeObj = [[1, "a", "b"], [2, "b", "a"]];
arrayLikeObj.names = ["m", "n", "o"];
var JSONCopy = JSONClone(arrayLikeObj);
var jQueryCopy = jQueryClone(arrayLikeObj);

alert("Is arrayLikeObj an array instance?" + (arrayLikeObj instanceof Array) +
      "\nIs the jQueryClone an array instance? " + (jQueryCopy instanceof Array) +
      "\nWhat are the arrayLikeObj names? " + arrayLikeObj.names +
      "\nAnd what are the JSONClone names? " + JSONCopy.names)
 

16







Amac─▒n─▒z─▒n "d├╝z eski JavaScript nesnesi" ni kopyalay─▒p kopyalamamas─▒na ba─čl─▒ olarak iki iyi cevab─▒m var.

Ayr─▒ca niyetinizin kaynak nesneye prototip referans─▒ olmayan tam bir klon olu┼čturmak oldu─čunu varsayal─▒m. Tam bir klonla ilgilenmiyorsan─▒z, di─čer cevaplar─▒n baz─▒lar─▒nda (Crockford'un d├╝zeni) verilen Object.clone () yordamlar─▒n─▒ kullanabilirsiniz.

Eski JavaScript nesneleri i├žin, modern ├žal─▒┼čma zamanlar─▒nda bir nesneyi klonlaman─▒n denenmi┼č ve ger├žek bir iyi yolu olduk├ža basit:

 var clone = JSON.parse(JSON.stringify(obj));
 

Kaynak nesnenin saf bir JSON nesnesi olmas─▒ gerekti─čini unutmay─▒n. Bu, i├ž i├že ge├žmi┼č ├Âzelliklerinin hepsinin skaler olmas─▒ gerekti─čidir (├Ârne─čin, boolean, string, array, object, vs.). RegExp veya Date gibi hi├žbir i┼člev veya ├Âzel nesne klonlanmayacakt─▒r.

Verimli mi? Heck evet. Her t├╝rl├╝ klonlama y├Ântemini denedik ve bu en iyisidir. Eminim baz─▒ ninjalar daha h─▒zl─▒ bir y├Ântem ortaya koyabilir. Ama marjinal kazan├žlar hakk─▒nda konu┼čtu─čumuzdan ┼č├╝pheleniyorum.

Bu yakla┼č─▒m sadece basit ve uygulanmas─▒ kolayd─▒r. Bir rahatl─▒k fonksiyonuna sar─▒n ve ger├žekten bir miktar kazan├ž sa─člaman─▒z gerekirse, daha sonra devam edin.

┼×imdi, d├╝z olmayan JavaScript nesneleri i├žin ger├žekten basit bir cevap yok. Asl─▒nda, JavaScript i┼člevlerinin ve i├ž nesne durumunun dinamik do─čas─▒ nedeniyle olamaz. Bir JSON yap─▒s─▒n─▒ i├žindeki i┼člevlerle derin klonlamak, bu i┼člevleri ve i├ž ba─člamlar─▒n─▒ yeniden yaratman─▒z─▒ gerektirir. Ve JavaScript'in bunu yapman─▒n standart bir yolu yoktur.

Bunu yapman─▒n do─čru yolu, bir kez daha, kodunuzda beyan etti─činiz ve yeniden kulland─▒─č─▒n─▒z bir kolayl─▒k y├Ântemidir. Kolayl─▒k y├Ântemi, kendi nesnelerinizi anlaman─▒za yard─▒mc─▒ olabilir, b├Âylece grafi─či yeni nesnede uygun ┼čekilde yeniden olu┼čturabildi─činizden emin olabilirsiniz.

Biz kendimiz yaz─▒yoruz, ancak g├Ârd├╝─č├╝m en iyi genel yakla┼č─▒m burada ele al─▒nacak:

http://davidwalsh.name/javascript-clone

Bu do─čru fikir. Yazar (David Walsh) genelle┼čtirilmi┼č fonksiyonlar─▒n klonlanmas─▒n─▒ yorumlam─▒┼čt─▒r. Bu, kullan─▒m durumunuza ba─čl─▒ olarak yapmay─▒ se├žebilece─činiz bir ┼čeydir.

Ana fikir, i┼člevlerinizin (veya prototip s─▒n─▒flar─▒n─▒n konu┼čmas─▒) her bir t├╝r temelinde ├Âzel olarak ele al─▒nmas─▒ gerekti─čidir. Burada, RegExp ve Date i├žin birka├ž ├Ârnek verdi.

Bu kod sadece k─▒sa de─čil, ayn─▒ zamanda ├žok okunakl─▒. Uzatmas─▒ olduk├ža kolay.

Bu verimli mi? Heck evet. Hedef, ger├žek bir derin kopya klonu ├╝retmek oldu─ču i├žin, kaynak nesne grafi─činin ├╝yelerini y├╝r├╝mek zorunda kalacaks─▒n─▒z. Bu yakla┼č─▒mla, tam olarak hangi alt ├╝yelerin davranaca─č─▒n─▒ ve ├Âzel t├╝rlerin elle nas─▒l ele al─▒naca─č─▒n─▒ d├╝zenleyebilirsiniz.

Al i┼čte ozaman, buyur. ─░ki yakla┼č─▒m. Her ikisi de benim g├Âr├╝┼č├╝me g├Âre verimli.


15







Bu genellikle en verimli ├ž├Âz├╝m de─čil, ancak ihtiyac─▒m olan─▒ yap─▒yor. A┼ča─č─▒daki basit test durumlar─▒ ...

 function clone(obj, clones) {
    // Makes a deep copy of 'obj'. Handles cyclic structures by
    // tracking cloned obj's in the 'clones' parameter. Functions 
    // are included, but not cloned. Functions members are cloned.
    var new_obj,
        already_cloned,
        t = typeof obj,
        i = 0,
        l,
        pair; 

    clones = clones || [];

    if (obj === null) {
        return obj;
    }

    if (t === "object" || t === "function") {

        // check to see if we've already cloned obj
        for (i = 0, l = clones.length; i < l; i++) {
            pair = clones[i];
            if (pair[0] === obj) {
                already_cloned = pair[1];
                break;
            }
        }

        if (already_cloned) {
            return already_cloned; 
        } else {
            if (t === "object") { // create new object
                new_obj = new obj.constructor();
            } else { // Just use functions as is
                new_obj = obj;
            }

            clones.push([obj, new_obj]); // keep track of objects we've cloned

            for (key in obj) { // clone object members
                if (obj.hasOwnProperty(key)) {
                    new_obj[key] = clone(obj[key], clones);
                }
            }
        }
    }
    return new_obj || obj;
}
 

D├Âng├╝sel dizi testi ...

 a = []
a.push("b", "c", a)
aa = clone(a)
aa === a //=> false
aa[2] === a //=> false
aa[2] === a[2] //=> false
aa[2] === aa //=> true
 

Fonksiyon testi...

 f = new Function
f.a = a
ff = clone(f)
ff === f //=> true
ff.a === a //=> false
 

13







angularjs

E─čer a├ž─▒sal kullan─▒yorsan─▒z, bunu da yapabilirsiniz.

 var newObject = angular.copy(oldObject);
 

12







Buradaki en b├╝y├╝k oylar─▒n cevab─▒na kat─▒lm─▒yorum . Bir ├Âzyinelemeli Derin Clone oldu─čunu ├žok daha h─▒zl─▒ daha JSON.parse (JSON.stringify (obj)) s├Âz konusu yakla┼č─▒m.

Ve i┼čte h─▒zl─▒ ba┼čvuru fonksiyonu:

 function cloneDeep (o) {
  let newO
  let i

  if (typeof o !== 'object') return o

  if (!o) return o

  if (Object.prototype.toString.apply(o) === '[object Array]') {
    newO = []
    for (i = 0; i < o.length; i += 1) {
      newO[i] = cloneDeep(o[i])
    }
    return newO
  }

  newO = {}
  for (i in o) {
    if (o.hasOwnProperty(i)) {
      newO[i] = cloneDeep(o[i])
    }
  }
  return newO
}
 

11







 // obj target object, vals source object
var setVals = function (obj, vals) {
    if (obj && vals) {
        for (var x in vals) {
            if (vals.hasOwnProperty(x)) {
                if (obj[x] && typeof vals[x] === 'object') {
                    obj[x] = setVals(obj[x], vals[x]);
                } else {
                    obj[x] = vals[x];
                }
            }
        }
    }
    return obj;
};
 

11







Kullanmak isteyenler i├žin JSON.parse(JSON.stringify(obj)) s├╝r├╝m, ancak tarihi nesneleri kaybetmeden kullanabilirsiniz ikinci arg├╝man parse y├Ântemine dizeleri Tarihi geri d├Ân├╝┼čt├╝rmek i├žin:

 function clone(obj) {
  var regExp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
  return JSON.parse(JSON.stringify(x), function(k, v) {
    if (typeof v === 'string' && regExp.test(v))
      return new Date(v);
    return v;
  });
}
 

9







─░┼čte herhangi bir JavaScript nesnesini klonlayabilen kapsaml─▒ bir clone () y├Ântemi. Neredeyse t├╝m vakalar─▒ ele al─▒yor:

 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;
};
 

8



─░lgili yay─▒nlar


JQuery kullanarak HTML ├Â─čeleri olu┼čturman─▒n en etkili yolu nedir?

Pandalar ile dataframe'ler aras─▒nda dola┼čman─▒n en etkili yolu nedir? [├žift]

N dizisini birle┼čtirmek i├žin en etkili yol nedir?

Etiketleri bir veritaban─▒nda saklaman─▒n en etkili yolu nedir?

Bir listeyi Django modellerinde saklaman─▒n en etkili yolu nedir?

Bir nesnenin say─▒ olup olmad─▒─č─▒n─▒ kontrol etmenin en pythonic yolu nedir?

Se├žili ├Â─čeyi koruyarak, bir HTML Se├žme Se├ženeklerini de─čere g├Âre s─▒ralaman─▒n en etkili yolu nedir?

Bir bayt dizisini C# diskinde dosya olarak kaydetmenin en etkili yolu nedir?

NSSet'i s─▒ralaman─▒n en etkili yolu nedir?

Bir int'yi bir String'e d├Ân├╝┼čt├╝rmenin en etkili yolu nedir?

Etiketle ilgili di─čer sorular [javascript]


ÔÇťAna s─▒n─▒f bulunamad─▒ ya da y├╝klenemediÔÇŁ ne demek?

Wait () ve sleep () aras─▒ndaki fark

Birisi __all__'u Python'da a├ž─▒klayabilir mi?

De─či┼čken t├╝r├╝n├╝n string olup olmad─▒─č─▒n─▒ nas─▒l kontrol edebilirim?

Vim bo┼č sat─▒rlar─▒ silmek

Git her bas─▒┼č─▒mda kullan─▒c─▒ ad─▒ istiyor

Android de─či┼čen Y├╝zen Eylem D├╝─čme rengi

Senkronize Blok yerine Senkronize Y├Ântem kullanma avantaj─▒ var m─▒?

Oracle: UPSERT nas─▒l yap─▒l─▒r (bir tabloya g├╝ncelleme veya ekleme?)

Twitter'─▒n Bootstrap'─▒ndaki d├╝─čmeyi devre d─▒┼č─▒ b─▒rakman─▒n en iyi yolu