আমি কীভাবে একটি জাভাস্ক্রিপ্ট অবজেক্টটিকে সঠিকভাবে ক্লোন করব?


3075

আমি একটি বস্তুর আছে x। আমি এটিকে অবজেক্ট হিসাবে অনুলিপি করতে চাই y, যেমন পরিবর্তন হয় yনা x। আমি বুঝতে পেরেছি যে অন্তর্নির্মিত জাভাস্ক্রিপ্ট অবজেক্টগুলি থেকে উত্পন্ন উত্সগুলি অনুলিপি করার ফলে অতিরিক্ত, অযাচিত বৈশিষ্ট্য হবে। এটি কোনও সমস্যা নয়, যেহেতু আমি আমার নিজের আক্ষরিক নির্মিত নির্মিত জিনিসগুলির অনুলিপি করছি।

আমি কীভাবে একটি জাভাস্ক্রিপ্ট অবজেক্টটিকে সঠিকভাবে ক্লোন করব?


30
এই প্রশ্নটি দেখুন: স্ট্যাকওভারফ্লো.com
নিয়াজ

256
জেএসএনের জন্য, আমি ব্যবহার করিmObj=JSON.parse(JSON.stringify(jsonObject));
লর্ড লোহ।

67
আমি সত্যিই পাই না কেন কেন কেউ পরামর্শ দেয় না Object.create(o), এটি লেখক যা কিছু জিজ্ঞাসা করে তা করে?
ব্যাঙবাড়ী

43
var x = { deep: { key: 1 } }; var y = Object.create(x); x.deep.key = 2; এটি করার পরে, y.deep.keyএটিও 2 হবে, সুতরাং অবজেক্ট ক্রিয়েট ক্লোনিংয়ের জন্য ব্যবহার করা যাবে না ...
রুবেন স্টলক

17
@ r3wt যা কাজ করবে না ... দয়া করে সমাধানের প্রাথমিক পরীক্ষা করার পরে পোস্ট করুন ..
অক্ষয়

উত্তর:


1560

জাভাস্ক্রিপ্টে কোনও অবজেক্টের জন্য এটি করা সহজ বা সোজা হবে না। আপনি ভ্রান্তভাবে অবজেক্টের প্রোটোটাইপ থেকে এমন বৈশিষ্ট্য বাছাইয়ের সমস্যায় পড়বেন যা প্রোটোটাইপে রেখে দেওয়া উচিত এবং নতুন দৃষ্টান্তে অনুলিপি করা উচিত নয়। উদাহরণস্বরূপ, যদি আপনি কোনও cloneপদ্ধতি যুক্ত করছেন তবে Object.prototypeকিছু উত্তর বর্ণিত হিসাবে, আপনাকে অবশ্যই সেই বৈশিষ্ট্যটি এড়িয়ে যেতে হবে ip তবে আপনি যদি জানেন না এমন অতিরিক্ত অতিরিক্ত পদ্ধতিগুলি Object.prototypeবা অন্যান্য মধ্যবর্তী প্রোটোটাইপগুলি যুক্ত করা হয় তবে কী হবে ? সেক্ষেত্রে, আপনার যে বৈশিষ্ট্যগুলি করা উচিত নয় তা অনুলিপি করবেন, সুতরাং আপনাকে hasOwnPropertyপদ্ধতির সাথে অপ্রত্যাশিত, অ-স্থানীয় বৈশিষ্ট্য সনাক্ত করতে হবে ।

অগণিত গুণাবলী ছাড়াও, আপনি যখন লুকানো বৈশিষ্ট্যযুক্ত বস্তুগুলি অনুলিপি করার চেষ্টা করবেন তখন আপনি আরও শক্ত সমস্যার মুখোমুখি হবেন। উদাহরণস্বরূপ, prototypeএকটি ফাংশনের একটি লুকানো সম্পত্তি। এছাড়াও, কোনও অবজেক্টের প্রোটোটাইপটি বৈশিষ্ট্যটির সাথে উল্লেখ করা হয় __proto__, যা লুকানোও রয়েছে এবং উত্স অবজেক্টের বৈশিষ্ট্যগুলির জন্য একটি / ইন লুপ পুনরাবৃত্তি করে অনুলিপি করা হবে না। আমি মনে করি __proto__ফায়ারফক্সের জাভাস্ক্রিপ্ট ইন্টারপ্রেটারের সাথে সুনির্দিষ্ট হতে পারে এবং এটি অন্য ব্রাউজারগুলিতে আলাদা কিছু হতে পারে তবে আপনি ছবিটি পান। সবকিছুই গণনার মতো নয়। আপনি যদি একটি লুকানো বৈশিষ্ট্যটির নাম জানেন তবে এটি অনুলিপি করতে পারেন, তবে স্বয়ংক্রিয়ভাবে এটি আবিষ্কার করার কোনও উপায় আমি জানি না।

একটি মার্জিত সমাধানের সন্ধানের মধ্যে আরও একটি ছদ্মবেশ হ'ল প্রোটোটাইপ উত্তরাধিকার সঠিকভাবে সেট আপ করার সমস্যা। যদি আপনার উত্স অবজেক্টের প্রোটোটাইপটি থাকে Objectতবে কেবল একটি নতুন সাধারণ অবজেক্ট তৈরি করা কার্যকর {}হবে তবে উত্সটির প্রোটোটাইপ যদি কিছু বংশধর হয় Objectতবে আপনি hasOwnPropertyফিল্টারটি ব্যবহার করে এড়িয়ে গেছেন এমন প্রোটোটাইপ থেকে অতিরিক্ত সদস্য নিখোঁজ হতে চলেছেন বা যা প্রোটোটাইপ ছিল, কিন্তু প্রথম স্থানে ছিল না গণনাযোগ্য। প্রাথমিক সমাধানের অবজেক্টটি পাওয়ার জন্য উত্স অবজেক্টের constructorসম্পত্তি কল করা এবং তারপরে বৈশিষ্ট্যগুলি অনুলিপি করা হতে পারে এর একটি সমাধান হতে পারে তবে তারপরেও আপনি অ-গুণিত গুণাবলী পাবেন না। উদাহরণস্বরূপ, কোনও Dateঅবজেক্ট তার ডেটা লুকানো সদস্য হিসাবে সঞ্চয় করে:

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

তারিখের স্ট্রিংটি এর d1চেয়ে 5 সেকেন্ড পিছনে থাকবে d2। একটিকে Dateঅন্যের মতো করে তোলার একটি উপায় setTimeপদ্ধতিটি কল করা , তবে এটি Dateশ্রেণীর সাথে নির্দিষ্ট । আমি মনে করি না যে এই সমস্যার কোনও বুলেট-প্রুফ সাধারণ সমাধান আছে, যদিও আমি ভুল হতে পেরে খুশি হব!

যখন আমি কপি আমি অভিমানী যে আমি শুধুমাত্র কপি করা একটি প্লেইন হবে দ্বারা সন্দেহজনক শেষ পর্যন্ত সাধারণ গভীর বাস্তবায়ন ছিল Object, Array, Date, String, Number, অথবা Boolean। শেষ 3 প্রকারগুলি অপরিবর্তনীয়, তাই আমি অগভীর অনুলিপি সম্পাদন করতে পারতাম এবং এটি পরিবর্তনের বিষয়ে চিন্তা করবো না। আমি আরও ধরে নিয়েছি যে যে কোনও উপাদান রয়েছে Objectবা Arrayসেগুলিও সেই তালিকায় থাকা 6 সাধারণ ধরণের একটি। এটি নিম্নলিখিত মত কোড দিয়ে সম্পন্ন করা যেতে পারে:

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.");
}

উপরোক্ত ফাংশনটি আমি উল্লেখ করা 6 টি সহজ ধরণের জন্য পর্যাপ্তভাবে কাজ করবে, যতক্ষণ না অবজেক্ট এবং অ্যারেতে থাকা ডেটা গাছের কাঠামো গঠন করে। অর্থাৎ, অবজেক্টে একই ডেটারে একাধিক উল্লেখ নেই। উদাহরণ স্বরূপ:

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

এটি কোনও জাভাস্ক্রিপ্ট অবজেক্ট হ্যান্ডেল করতে সক্ষম হবে না, তবে এটি যতক্ষণ না ধরে নিবেন যে এটি এটি আপনি ফেলে দেওয়া কোনও কিছুর জন্যই কাজ করবে যতক্ষণ না ধরে নেবেন এটি অনেকগুলি উদ্দেশ্যে যথেষ্ট।


5
একটি নোডেজে প্রায় ভাল কাজ করেছে - কেবল (var i = 0, var len = obj.length; i <len; ++ i) for এর জন্য (var i = 0; i <obj.length;) এর জন্য লাইনটি পরিবর্তন করতে হয়েছিল; ++ i) {
ত্রিনদাজ

5
ভবিষ্যতের গুগলদের জন্য: একই গভীর অনুলিপি, gist.github.com/2234277
ত্রিঞ্জাজ

7
আজকাল কি JSON.parse(JSON.stringify([some object]),[some revirer function])সমাধান হবে?
KooiInc

5
প্রথম স্নিপেটে, আপনি কি নিশ্চিত যে এটি হওয়া উচিত নয় var cpy = new obj.constructor()?
সাইমন

8
অবজেক্ট অ্যাসাইন Chrome এ সত্যিকারের অনুলিপি তৈরি করে বলে মনে হচ্ছে না, আসল অবজেক্টের রেফারেন্স বজায় রাখে - JSON.stringify এবং JSON.parse ব্যবহার করে ক্লোন করতে পেরেছে - নিখুঁতভাবে কাজ করেছে
1owk3y

974

আপনি যদি Dateনিজের অবজেক্টের মধ্যে s, ফাংশন, অপরিজ্ঞাত, regExp বা ইনফিনিটি ব্যবহার না করেন তবে খুব সাধারণ একটি লাইনার হ'ল 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()

এটি অবজেক্টস, অ্যারে, স্ট্রিং, বুলিয়ান এবং সংখ্যাযুক্ত সমস্ত ধরণের অবজেক্টের জন্য কাজ করে।

ব্রাউজারগুলির কাঠামোগত ক্লোন অ্যালগরিদম সম্পর্কে এই নিবন্ধটিও দেখুন যা কোনও শ্রমিকের কাছে এবং তার থেকে বার্তা পোস্ট করার সময় ব্যবহৃত হয়। এটি গভীর ক্লোনিংয়ের জন্য একটি ফাংশনও অন্তর্ভুক্ত করে।


42
মনে রাখবেন এটি কেবল পরীক্ষার জন্য ব্যবহার করা যেতে পারে। প্রথমত, সময় এবং মেমরির ব্যবহারের ক্ষেত্রে এটি সর্বোত্তম থেকে অনেক দূরে। দ্বিতীয়ত, সমস্ত ব্রাউজারের এই পদ্ধতিগুলি থাকে না।
Nux

2
আপনি সর্বদা JSON2.js বা JSON3.js অন্তর্ভুক্ত করতে পারেন। যাইহোক আপনার অ্যাপ্লিকেশনের জন্য আপনার এগুলির প্রয়োজন হবে। তবে আমি সম্মত হই যে এটি সর্বোত্তম সমাধান হতে পারে না, যেহেতু JSON.stringify উত্তরাধিকারসূত্রে প্রাপ্ত বৈশিষ্ট্যগুলিকে অন্তর্ভুক্ত করে না।
টিম হং

78
@ নাক্স, সময় এবং স্মৃতিশক্তি হিসাবে কেন সর্বোত্তম নয়? মিজিন বলেছেন: "এই পদ্ধতিটি অগভীর অনুলিপি (একটি গভীর বস্তুতে) এর চেয়ে ধীর হওয়ার কারণটি হ'ল এই পদ্ধতিটি, সংজ্ঞা অনুসারে, গভীর অনুলিপিগুলি But তবে যেহেতু জেএসওএন স্থানীয় কোডে প্রয়োগ করা হয় (বেশিরভাগ ব্রাউজারগুলিতে), এটি যথেষ্ট দ্রুত হবে অন্য কোনও জাভাস্ক্রিপ্ট-ভিত্তিক গভীর অনুলিপি সমাধান ব্যবহার করার চেয়ে, এবং কখনও কখনও জাভাস্ক্রিপ্ট-ভিত্তিক অগভীর অনুলিপি করার কৌশলটির চেয়ে দ্রুত হতে পারে (দেখুন: jsperf.com/cloning-an-object/79) " stackoverflow.com/questions/122102/...
BeauCielBleu

16
আমি কেবল অক্টোবর ২০১৪ এর জন্য এটিতে একটি আপডেট যুক্ত করতে চাই Chrome এটি ব্যবহারের সুবিধাটি হ'ল জাভাস্ক্রিপ্ট ইঞ্জিনের পক্ষে এটি চাইলে আরও ভাল কিছু দেখার এবং এটি অনুকূলকরণ করা খুব সহজ।
মিরহাক্ক

17
২০১ update আপডেট: এখন প্রতিটি ব্রাউজারের ব্যাপকভাবে ব্যবহৃত হচ্ছে এমন কাজ করা উচিত। (দেখুন আমি কী ব্যবহার করতে পারি ... ) এখন মূল প্রশ্নটি হবে এটি যথেষ্ট পারফরম্যান্ট কিনা।
জেমস ফস্টার

783

JQuery সঙ্গে, আপনি পারবেন অগভীর কপি সঙ্গে প্রসারিত :

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

পরবর্তী পরিবর্তনগুলি copiedObjectপ্রভাব ফেলবে না originalObjectএবং বিপরীতে।

অথবা একটি গভীর অনুলিপি তৈরি করতে :

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

164
বা এমনকি:var copiedObject = jQuery.extend({},originalObject);
গ্রান্ট ম্যাকলিন

82
গভীর অনুলিপিটির জন্য প্রথম পরম হিসাবে সত্য উল্লেখ করতেও দরকারী:jQuery.extend(true, {}, originalObject);
শেভ

6
হ্যাঁ, আমি এই লিঙ্কটি সহায়ক (পাসকালের মতো একই সমাধান) পেয়েছি স্ট্যাকওভারফ্লো.com
গ্যারি ইংলিশ

3
কেবল একটি নোট, এটি আসল অবজেক্টের প্রোটো কনস্ট্রাক্টরকে অনুলিপি করে না
স্যাম জোন্স

1
স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 184710/… অনুসারে , মনে হচ্ছে "অগভীর অনুলিপি" কেবলমাত্র অরিজিনাল অবজেক্টের রেফারেন্সটি অনুলিপি করে, সুতরাং এখানে কেন এটি বলা হয়েছে ...subsequent changes to the copiedObject will not affect the originalObject, and vice versa...। দুঃখিত যে আমি সত্যিই বিভ্রান্ত ছিলাম।
ক্যার

684

ইসমাস্ক্রিপ্ট In- তে অবজেক্ট.সেসাইন পদ্ধতি রয়েছে যা সমস্ত গণনাকারী নিজস্ব সম্পত্তিগুলির মানগুলি একটি বস্তু থেকে অপরটিতে অনুলিপি করে। উদাহরণ স্বরূপ:

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

তবে সচেতন হন যে নেস্টেড অবজেক্টগুলি এখনও রেফারেন্স হিসাবে অনুলিপি করা হয়েছে।


হ্যাঁ, আমি বিশ্বাস করি Object.assignএটিই চলার পথ। এটিও পলিফিল করা সহজ: gist.github.com/rafaelrinaldi/43813e707970bd2d77fa

22
এছাড়াও জেনে রাখুন যে এই "পদ্ধতি" অবজেক্ট লিটারেল মাধ্যমে সংজ্ঞায়িত সময় অনুলিপি হবে (যেহেতু এই হয় কিন্তু গণনীয়) না "শ্রেণী" প্রক্রিয়া মাধ্যমে হার মানিয়েছে পদ্ধতি (যেহেতু এই নয় গণনীয়)।
মার্কাস জুনিয়াস ব্রুটাস

16
আমি মনে করি যে উল্লেখ করা উচিত যে এটি এজ ব্যতীত IE দ্বারা সমর্থিত নয়। কিছু লোক এখনও এটি ব্যবহার করে।
সাওলিয়াস

1
এটি তাঁর উত্তর @ ইউজিনটিউরিনের মতোই।
উইল

5
অভিজ্ঞতা থেকে এখানে বলছি ... এটি ব্যবহার করবেন না। অবজেক্টগুলি হায়ারার্কিকাল হিসাবে ডিজাইন করা হয়েছে এবং আপনি কেবলমাত্র প্রথম স্তরটি অনুলিপি করেছেন, আপনাকে পুরো অবজেক্টটি অনুলিপি করার জন্য নেতৃত্ব দিচ্ছে। বিশ্বাস করুন, এটি আপনার মাথা চুলকানোর দিনগুলি বাঁচাতে পারে।
ow3n

232

প্রতি এমডিএন :

  • আপনি যদি অগভীর অনুলিপি চান তবে ব্যবহার করুন Object.assign({}, a)
  • "গভীর" অনুলিপি জন্য, ব্যবহার করুন JSON.parse(JSON.stringify(a))

বাহ্যিক গ্রন্থাগারের প্রয়োজন নেই তবে আপনাকে প্রথমে ব্রাউজারের সামঞ্জস্যতা পরীক্ষা করতে হবে ।


8
JSON.parse (JSON.stringify (a)) দেখতে দেখতে সুন্দর লাগছে তবে এটি ব্যবহার করার আগে আমি আপনার কাঙ্ক্ষিত সংগ্রহের জন্য যে সময় নেয় তা বেঞ্চমার্ক করার পরামর্শ দিচ্ছি। বস্তুর আকারের উপর নির্ভর করে, এটি মোটেও দ্রুত বিকল্প নাও হতে পারে।
এডজা

3
JSON পদ্ধতি আমি লক্ষ্য করেছি যে তারিখের বস্তুগুলিকে স্ট্রিংয়ে রূপান্তরিত করা হয় তবে তারিখগুলিতে ফিরে আসে না। জাভাস্ক্রিপ্টে টাইম জোনের মজাদার সাথে মোকাবেলা করতে হবে এবং যেকোন তারিখ নিজেই ঠিক করতে হবে। তারিখগুলি ছাড়াও অন্যান্য ধরণের ক্ষেত্রে একই ধরণের ঘটনা হতে পারে
স্টিভ সিগার

তারিখের জন্য, আমি moment.js ব্যবহার করব কারণ এটির cloneকার্যকারিতা রয়েছে। এখানে আরও দেখুন momentjs.com/docs/#/parsing/moment-clone
তারেক

এটি ভাল তবে যদি অবজেক্টটির ভিতরে ফাংশন থাকে তবে যত্ন নিন
লেসোলোরজানোভ

জেসন পার্সিংয়ের সাথে আরেকটি সমস্যা হ'ল বৃত্তাকার উল্লেখ। যদি অবজেক্টের অভ্যন্তরে কোনও বিজ্ঞপ্তি উল্লেখ থাকে, তবে এটি ভেঙে যাবে
ফিলিজ

133

অনেকগুলি উত্তর রয়েছে, তবে কোনওটিই ECMAScript 5 থেকে অবজেক্ট.ক্রিয়েটের কথা উল্লেখ করে নি, যা স্বীকার করে আপনাকে একটি সঠিক অনুলিপি দেয় না , তবে উত্সটিকে নতুন অবজেক্টের প্রোটোটাইপ হিসাবে সেট করে।

সুতরাং, এটি প্রশ্নের সঠিক উত্তর নয়, তবে এটি একটি এক-লাইন সমাধান এবং এইভাবে মার্জিত। এবং এটি 2 টি ক্ষেত্রে সবচেয়ে ভাল কাজ করে:

  1. যেখানে এই জাতীয় উত্তরাধিকার দরকারী (দুহ!)
  2. যেখানে উত্স অবজেক্টটি সংশোধন করা হবে না, এইভাবে 2 টি বস্তুর মধ্যে সম্পর্কটিকে একটি নন ইস্যু করে তোলে।

উদাহরণ:

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

আমি কেন এই সমাধানটিকে উচ্চতর হিসাবে বিবেচনা করব? এটি নেটিভ, এইভাবে কোনও লুপিং নেই, পুনরাবৃত্তি হবে না। তবে, পুরানো ব্রাউজারগুলির একটি পলিফিল লাগবে।


দ্রষ্টব্য: অবজেক্ট.ক্রিয়েট কোনও গভীর অনুলিপি নয় (এটি পূর্বে কোনও পুনরাবৃত্তির উল্লেখ নেই)। প্রমাণ:var a = {b:'hello',c:{d:'world'}}, b = Object.create(a); a == b /* false */; a.c == b.c /* true */;
জামনটস

103
এটি প্রোটোটাইপাল উত্তরাধিকার, ক্লোনিং নয়। এগুলি সম্পূর্ণ আলাদা জিনিস। নতুন বস্তুর নিজস্ব কোনও বৈশিষ্ট্য নেই, এটি কেবল প্রোটোটাইপের বৈশিষ্ট্যগুলিকে নির্দেশ করে। ক্লোনিংয়ের বিষয়টি হ'ল একটি নতুন নতুন অবজেক্ট তৈরি করা যা অন্য কোনও বস্তুর কোনও বৈশিষ্ট্য উল্লেখ করে না।
d13

7
আমি তোমার সাথে সম্পূর্ণ একমত. আমি এটিও সম্মত করি যে এটি 'উদ্দেশ্য' হিসাবে ক্লোনিং নয় oning তবে লোকেরা আসুন, মানক নয় এমন অস্পষ্ট সমাধানগুলি সন্ধান করার পরিবর্তে জাভাস্ক্রিপ্টের প্রকৃতি আলিঙ্গন করুন। অবশ্যই, আপনি প্রোটোটাইপগুলি পছন্দ করেন না এবং সেগুলি আপনার কাছে সমস্ত "বেলা", তবে আপনি কী করছেন তা যদি তারা জানেন তবে এগুলি আসলে খুব কার্যকর are
ব্যাঙমুক্তি

4
@ রবজি: এই নিবন্ধটি রেফারেন্সিং এবং ক্লোনিংয়ের মধ্যে পার্থক্য ব্যাখ্যা করেছে: এন.ইউইউইকিপিডিয়া.আর / উইকি / ক্লোনিং_জেড প্রোগ্রামিং )Object.createরেফারেন্সের মাধ্যমে পিতামাতার সম্পত্তিগুলিকে নির্দেশ করে hat এর অর্থ যদি পিতামাতার সম্পত্তির মান পরিবর্তন হয় তবে সন্তানেরও পরিবর্তন হবে। নেস্টেড অ্যারে এবং অবজেক্টগুলির সাথে এর কিছু বিস্ময়কর পার্শ্ব-প্রতিক্রিয়া রয়েছে যা যদি আপনি তাদের সম্পর্কে অবগত না হন তবে আপনার কোডটিতে হার্ড-টু-বাগ খুঁজে পেতে পারে: jsbin.com/EKivInO/2 । একটি ক্লোন করা বস্তু একটি সম্পূর্ণ নতুন, স্বতন্ত্র অবজেক্ট যা পিতামাতার মতো একই বৈশিষ্ট্য এবং মান রয়েছে তবে পিতামাতার সাথে সংযুক্ত নেই।
d13

1
এটি মানুষকে বিভ্রান্ত করে ... অবজেক্ট.ক্রিয়েট () উত্তরাধিকারের জন্য একটি উপায় হিসাবে ব্যবহার করা যেতে পারে তবে ক্লোনিং এর কাছাকাছি কোথাও নেই।
প্রজ্ঞাবন্ধ

128

কোডের এক লাইনে জাভাস্ক্রিপ্ট অবজেক্টটি ক্লোন করার একটি দুর্দান্ত উপায়

একটি Object.assignপদ্ধতি ECMAScript 2015 (ES6) স্ট্যান্ডার্ডের একটি অংশ এবং আপনার যা প্রয়োজন ঠিক তা করে।

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

অবজেক্ট.সেসাইন () পদ্ধতিটি এক বা একাধিক উত্স অবজেক্ট থেকে একটি লক্ষ্য অবজেক্টে সমস্ত পরিগণিত নিজস্ব সম্পত্তিগুলির মানগুলি অনুলিপি করতে ব্যবহৃত হয়।

আরও পড়ুন ...

Polyfill পুরোনো ব্রাউজারে সমর্থন করার জন্য:

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

বোবা প্রশ্নের জন্য দুঃখিত, তবে পলিফিলের ফাংশনটি Object.assignযখন valueকেবল একটি পরামিতি নেয় তখন কেন দুটি পরামিতি লাগে?
কিওয়ার্টি

@ কুয়ার্টি গতকাল সমস্ত যুক্তি পুনরুক্ত করা হয়েছে এবং একটি বস্তুকে একীভূত করা হয়েছে, শেষ হয়ে যাওয়া আর্গ থেকে সম্পত্তিটিকে অগ্রাধিকার দেওয়া হচ্ছে
ইউজিন টিউরিন

ওহ, দেখুন, ধন্যবাদ (আমি argumentsআগে এই জিনিসের সাথে পরিচিত ছিলাম না )) Object()গুগলের মাধ্যমে খুঁজে পেতে আমার সমস্যা হচ্ছে ... এটি টাইপকাস্ট, তাই না?
কিওয়ারটি

44
এটি কেবল একটি অগভীর "ক্লোনিং" সম্পাদন করবে
মার্কাস জুনিয়াস ব্রুটাস

1
এই উত্তরটি হুবহু হ'ল: স্ট্যাকওভারফ্লো / প্রশ্ন / 122102/… আমি জানি এটি একই ব্যক্তির দ্বারা হয় তবে আপনাকে কেবল উত্তরটি অনুলিপি না করে রেফারেন্স করা উচিত।
লেসোলোরাজানভ

86

ইন্টারনেটে বেশিরভাগ সমাধান নিয়ে বেশ কয়েকটি সমস্যা রয়েছে। সুতরাং আমি একটি ফলোআপ করার সিদ্ধান্ত নিয়েছি, যার মধ্যে রয়েছে, কেন গৃহীত উত্তরটি গ্রহণ করা উচিত নয়।

শুরুর অবস্থা

আমি একটি জাভাস্ক্রিপ্ট এর সমস্ত শিশু এবং তাদের বাচ্চাদের ইত্যাদির সাথে অনুলিপি করতে চাই Object। কিন্তু যেহেতু আমি একটি স্বাভাবিক ডেভেলপার ধরনের নই, আমার Objectহয়ে গেছে স্বাভাবিক properties , circular structuresএবং এমনকি nested objects

সুতরাং আসুন একটি circular structureএবং nested objectপ্রথম তৈরি করুন ।

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

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

আসুন একটি Objectনাম দিয়ে সব একত্রিত করা যাক a

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

এর পরে, আমরা aনামের একটি ভেরিয়েবলের অনুলিপি করতে bএবং এটি পরিবর্তন করতে চাই।

var b = a;

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

আপনি জানেন এখানে কী ঘটেছিল কারণ যদি না হয় তবে আপনি এই দুর্দান্ত প্রশ্নে অবতীর্ণ হন না।

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

এখন একটি সমাধান খুঁজে বের করা যাক।

তাদেরকে JSON

আমি প্রথম চেষ্টাটি ব্যবহার করেছিলাম JSON

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

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

এটিতে খুব বেশি সময় নষ্ট করবেন না, আপনি পাবেন TypeError: Converting circular structure to JSON

পুনরাবৃত্তির অনুলিপি (স্বীকৃত "উত্তর")

আসুন গৃহীত উত্তরটি একবার দেখুন।

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.");
}

ভাল লাগছে, হি? এটি অবজেক্টের পুনরাবৃত্তির অনুলিপি এবং অন্যান্য ধরণের হ্যান্ডলগুলিও পছন্দ করে Date, তবে এটি কোনও প্রয়োজন ছিল না।

var b = cloneSO(a);

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

পুনরাবৃত্তি এবং circular structuresএকসাথে ভাল কাজ করে না ...RangeError: Maximum call stack size exceeded

নেটিভ সমাধান

আমার সহকর্মীর সাথে তর্ক করার পরে, আমার বস আমাদের জিজ্ঞাসা করলেন কী ঘটেছে, এবং কিছুটা গুগল করার পরে তিনি একটি সহজ সমাধান পেয়েছিলেন । এটি বলা হয় Object.create

var b = Object.create(a);

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

কিছু সময় আগে এই সমাধানটি জাভাস্ক্রিপ্টে যুক্ত হয়েছিল এবং হ্যান্ডেলগুলিও 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"
    }
}

... এবং আপনি দেখুন, এটি নেস্টেড কাঠামোর সাথে কাজ করে নি।

স্থানীয় সমাধানের জন্য পলিফিল

Object.createআইই ৮ এর মতো পুরানো ব্রাউজারে একটি পলিফিল রয়েছে এটি মজিলার দ্বারা প্রস্তাবিত মতো কিছু এবং অবশ্যই এটি নিখুঁত নয় এবং দেশীয় সমাধান হিসাবে একই সমস্যার ফলস্বরূপ ।

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

var b = clonePF(a);

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

আমি Fসুযোগের বাইরে রেখেছি যাতে আমাদের কী instanceofবলছে তা আমাদের একবার দেখতে পারা যায় ।

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

দেশীয় সমাধান হিসাবে একই সমস্যা , তবে কিছুটা খারাপ ফলাফল।

ভাল (তবে নিখুঁত নয়) সমাধান

চারপাশে খনন করার সময়, আমি একটি অনুরূপ প্রশ্ন পেয়েছি ( জাভাস্ক্রিপ্টে, যখন একটি গভীর অনুলিপি সম্পাদন করা হচ্ছে, তবে আমি কোনও চক্রকে কীভাবে এড়িয়ে চলব, কোনও সম্পত্তির কারণে "এই"? ) থাকার কারণে , তবে এটির আরও ভাল সমাধান সহ।

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

এবং এর আউটপুট এক নজরে ...

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

প্রয়োজনীয়তা মেলানো হয়, কিন্তু এখনও কিছু ছোট বিষয়, পরিবর্তন সহ instanceএর nestedএবং circকরতে Object

একটি পাতা ভাগ করে এমন গাছের কাঠামো অনুলিপি করা হবে না, তারা দুটি স্বতন্ত্র পাতাতে পরিণত হবে:

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

উপসংহার

পুনরাবৃত্তি এবং ক্যাশে ব্যবহারের সর্বশেষ সমাধানটি সেরা নাও হতে পারে তবে এটি অবজেক্টের সত্যিকারের গভীর অনুলিপি। এটি সহজ পরিচালনা করে properties, circular structuresএবং nested object, তবে ক্লোনিং করার সময় এটির উদাহরণটি বিশৃঙ্খলা করবে।

jsfiddle


11
সুতরাং এই সমস্যা এড়াতে কনক্লিউশন হল :)
মিকাস

@ মাইকাস যতক্ষণ না আসল স্পেসিফিকেশন রয়েছে যা হ্যাঁ, কেবলমাত্র ব্যবহারিক ব্যবহারের চেয়ে বেশি কিছু জুড়ে।
ফ্যাবিও পোলোনি

2
উপরে প্রদত্ত সমাধানগুলির একটি ঠিকঠাক বিশ্লেষণ কিন্তু লেখকের আঁকা উপসংহার ইঙ্গিত দেয় যে এই প্রশ্নের কোনও সমাধান নেই।
আমির মোগ

2
এটি লজ্জাজনক যে জেএসে নেটিভ ক্লোন ফাংশন অন্তর্ভুক্ত নয়।
l00k

1
শীর্ষস্থানীয় সমস্ত উত্তরগুলির মধ্যে, আমি মনে করি এটি সঠিক উত্তরটির কাছাকাছি।
কেটিইউ

77

যদি আপনি অগভীর অনুলিপিটি দিয়ে ঠিক থাকেন তবে আন্ডারস্কোর.জেএস লাইব্রেরির ক্লোন পদ্ধতি রয়েছে।

y = _.clone(x);

অথবা আপনি এটির মতো প্রসারিত করতে পারেন

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

2
ধন্যবাদ। একটি উল্কা সার্ভারে এই কৌশলটি ব্যবহার করা।
টার্বো

লোডাস দিয়ে দ্রুত শুরু করার জন্য, আমি এনপিএম, ব্রাউজারিফাই, পাশাপাশি লোডাশ শিখার পরামর্শ দিই। আমি 'এনপিএম আই - সেভ লড্যাশ.ক্লোন' এর সাথে কাজ করতে পেরেছি এবং তারপরে 'ভার ক্লোন = প্রয়োজন (' লডাশক্লোন ');' কাজ করার জন্য আপনার ব্রাউজারিফাইয়ের মতো কিছু দরকার something একবার আপনি এটি ইনস্টল করে এবং এটি কীভাবে কাজ করে তা শিখলে, আপনি প্রতিটি বার আপনার কোড চালানোর সময় 'সরাসরি ব্রাউজ করুন yourfile.js> bundle.js; ক্রোম সূচক html শুরু করুন' (সরাসরি ক্রোমে যাওয়ার পরিবর্তে) ব্যবহার করবেন। এটি আপনার ফাইল এবং আপনার প্রয়োজনীয় সমস্ত ফাইল এনপিএম মডিউল থেকে bundle.js এ সংগ্রহ করে। আপনি সম্ভবত সময় সাশ্রয় করতে পারেন এবং এই পদক্ষেপটি গুলপের সাথে স্বয়ংক্রিয় করতে পারেন।
অ্যারন বেল

64

ঠিক আছে, কল্পনা করুন আপনার নীচে এই অবজেক্টটি রয়েছে এবং আপনি এটি ক্লোন করতে চান:

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

অথবা

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

উত্তরটি মূলত ছড়িয়ে দেওয়া হয় আপনি যে ইসিএমএসক্রিপ্টটি ব্যবহার করছেন তাতে আপনি ক্লোনটিES6+ করতে কেবল ব্যবহার Object.assignকরতে পারেন:

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

বা এই জাতীয় স্প্রেড অপারেটর ব্যবহার করুন:

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

তবে ES5আপনি যদি ব্যবহার করেন তবে কয়েকটি পদ্ধতি ব্যবহার করতে পারেন তবে JSON.stringifyকেবল এটি নিশ্চিত করুন যে আপনি অনুলিপি করার জন্য খুব বেশি পরিমাণে ডেটা ব্যবহার করছেন না, তবে এটি অনেক ক্ষেত্রে এক লাইনের উপায়ে হতে পারে, এরকম কিছু:

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

আপনি কি big chunk of dataসমান হবে উদাহরণ দিতে পারেন? 100 কিলোবাইটের? 100MB? ধন্যবাদ!
ব্যবহারকারীর 1063287

হ্যাঁ, @ ব্যবহারকারী 1063287, এটি মূলত বড় ডেটা, পারফরম্যান্স আরও খারাপ ... সুতরাং এটি সত্যিই নির্ভর করে, কোনও কেবি, এমবি বা জিবি নয়, আপনি আরও কতবার এটি করতে চান তা আরও বেশি ... এছাড়াও এটি কাজ করবে না ফাংশন এবং অন্যান্য স্টাফ জন্য ...
আলিরিজা

3
Object.assignঅগভীর অনুলিপি তৈরি করেছেন (ঠিক যেমন প্রচার, @ আলাইজেরা)
বোগদান ডি

আপনি es5 ঢুকতে ব্যবহার করতে পারবেন না: ^) @Alireza
SensationSama

40

একটি বিশেষভাবে অপ্রীতিকর সমাধান হ'ল জেএসএন এনকোডিং ব্যবহার করে সদস্য পদ্ধতি নেই এমন বস্তুর গভীর অনুলিপি তৈরি করতে। পদ্ধতিটি হল আপনার টার্গেট অবজেক্টটি জেএসনকে এনকোড করা, তারপরে ডিকোড করে আপনি যে অনুলিপিটি খুঁজছেন তা পেয়ে যাবেন। আপনার যতগুলি কপি প্রয়োজন হয় আপনি ততবার ডিকোড করতে পারেন।

অবশ্যই, ফাংশনগুলি JSON এর সাথে সম্পর্কিত নয়, সুতরাং এটি কেবল সদস্য পদ্ধতি ছাড়াই অবজেক্টগুলির জন্য কাজ করে।

এই পদ্ধতিটি আমার ব্যবহারের ক্ষেত্রে উপযুক্ত ছিল, যেহেতু আমি জেএসএন ব্লবগুলি একটি মূল-মান স্টোরে সংরক্ষণ করছি এবং যখন এটি কোনও জাভাস্ক্রিপ্ট এপিআইতে অবজেক্ট হিসাবে প্রকাশিত হয় তখন প্রতিটি বস্তুতে আসলে বস্তুর মূল অবস্থার অনুলিপি থাকে তাই আমরা কলার উদ্ভাসিত বস্তুকে রূপান্তরিত করার পরে ব-দ্বীপ গণনা করতে পারে।

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

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

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

ফাংশনগুলি JSON এর সাথে সম্পর্কিত নয় কেন? আমি তাদের আরও একবার JSON হিসাবে স্থানান্তরিত করতে দেখেছি ...
the_ড্রো

5
ফাংশনগুলি JSON স্পেসের অংশ নয়, কারণ তারা ডেটা স্থানান্তর করার কোনও সুরক্ষিত (বা স্মার্ট) উপায় নয়, যা জেএসএন এর জন্য তৈরি হয়েছিল। আমি জানি ফায়ারফক্সের নেটিভ জেএসএন এনকোডার সহজেই এতে দেওয়া ফাংশনগুলি উপেক্ষা করে তবে আমি অন্যের আচরণ সম্পর্কে নিশ্চিত নই।
ক্রিস ওয়াকার 10

1
@ চিহ্ন: { 'foo': function() { return 1; } }একটি আক্ষরিক নির্মিত নির্মিত বস্তু।
অবতারিত

@ বার্নার্ট ফাংশনগুলি ডেটা নয়। "ফাংশন লিটারালস" একটি ভুল ধারণা রয়েছে - যেহেতু ফাংশনগুলিতে অ্যাসাইনমেন্ট এবং সমস্ত ধরণের "অ-সিরিয়ালাইজযোগ্য" জিনিসগুলি সহ নির্বিচারে কোড থাকতে পারে।
vemv

35

রেফারেন্স ছাড়াই কোনও অবজেক্ট অনুলিপি করতে আপনি কেবল একটি স্প্রেড সম্পত্তি ব্যবহার করতে পারেন । তবে সাবধান হন (মন্তব্য দেখুন), 'অনুলিপি' কেবল সর্বনিম্ন অবজেক্ট / অ্যারে স্তরে। নেস্টেড সম্পত্তি এখনও রেফারেন্স!


সম্পূর্ণ ক্লোন:

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

// => mutate without references:

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

দ্বিতীয় স্তরের রেফারেন্স সহ ক্লোন করুন:

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

// => nested object is still a references:

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

জাভাস্ক্রিপ্ট প্রকৃতপক্ষে গভীর ক্লোনগুলি সমর্থন করে না। একটি ইউটিলিটি ফাংশন ব্যবহার করুন। যেমন রামদা:

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


1
এটি কাজ করছে না ... এটি সম্ভবত কাজ করবে যখন x উদাহরণস্বরূপ x = ['আব', 'সিডি', ...]
কামিল কিয়েসজেউস্কি

3
এটি কাজ করে, তবে মনে রাখবেন এটি একটি শুল্ক অনুলিপি, অতএব অন্যদের অবজেক্টগুলির জন্য গভীরতর রেফারেন্সগুলি রেফারেন্স থেকে যায়!
বাগস বানি 13

একটি আংশিক const first = {a: 'foo', b: 'bar'}; const second = {...{a} = first}
ক্লোনও

25

অ্যাংুলারজেএস ব্যবহারকারীদের জন্য, এই লাইব্রেরিতে অবজেক্টগুলির ক্লোনিং বা প্রসারিত করার জন্য সরাসরি পদ্ধতি রয়েছে।

var destination = angular.copy(source);

অথবা

angular.copy(source, destination);

Angular.copy ডকুমেন্টেশনে আরও ...


2
এটি একটি গভীর অনুলিপি এফওয়াইআই।
জামনেটস

22

এখানে আপনি ব্যবহার করতে পারেন একটি ফাংশন।

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

10
এই উত্তরটি বেশ কাছাকাছি, তবে পুরোপুরি সঠিক নয়। আপনি যদি কোনও তারিখের অবজেক্টটি ক্লোন করার চেষ্টা করেন তবে আপনি একই তারিখটি পাবেন না কারণ তারিখ নির্মাণকারী ফাংশনে কলটি বর্তমান তারিখ / সময় দিয়ে নতুন তারিখকে সূচনা করে। এই মানটি গণনীয় নয় এবং লুপের জন্য / ইন লুপ দ্বারা অনুলিপি করা হবে না।
এ লেভি

নিখুঁত নয়, তবে basic মৌলিক ক্ষেত্রে এটি চমৎকার। যেমন একটি আর্গুমেন্টের সাধারণ ক্লোনিংকে মঞ্জুরি দেয় যা কোনও মৌলিক অবজেক্ট, অ্যারে বা স্ট্রিং হতে পারে।
james_womack

কনস্ট্রাক্টরটি ব্যবহার করে সঠিকভাবে কল করার জন্য আপভোটড new। গৃহীত উত্তর দেয় না।
getFree

নোডে সব কিছু কাজ করে! এখনও রেফারেন্স লিঙ্কগুলি রেখে গেছে
ব্যবহারকারী 956584

পুনরাবৃত্তির চিন্তাভাবনা দুর্দান্ত ut তবে মানটি যদি অ্যারে হয় তবে এটি কাজ করবে?
Q10 ভাইকিং

22

এ। লাইভির উত্তরটি প্রায় সম্পূর্ণ, এখানে আমার সামান্য অবদান: পুনরাবৃত্ত তথ্যসূত্রগুলি কীভাবে পরিচালনা করতে হয় তার উপায় আছে , এই লাইনটি দেখুন

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

যদি বস্তুটি XML DOM উপাদান হয় তবে তার পরিবর্তে আমাদের অবশ্যই ক্লোননোড ব্যবহার করতে হবে

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

এ। লাইভির বিস্তৃত অধ্যয়ন এবং ক্যালভিনের প্রোটোটাইপিং পদ্ধতির দ্বারা অনুপ্রাণিত হয়ে আমি এই সমাধানটি দিচ্ছি:

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

উত্তরে অ্যান্ডি বার্কের নোটও দেখুন।


3
Date.prototype.clone = function() {return new Date(+this)};
রবজি

22

এই নিবন্ধ থেকে: ব্রায়ান হুইসমান দ্বারা জাভাস্ক্রিপ্টে অ্যারে এবং অবজেক্টগুলি কীভাবে অনুলিপি করবেন :

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

4
এটি নিকটে, তবে কোনও বস্তুর পক্ষে কাজ করে না। এটি দিয়ে একটি তারিখ অবজেক্টকে ক্লোন করার চেষ্টা করুন। সমস্ত বৈশিষ্ট্য গণনাযোগ্য নয়, সুতরাং সেগুলি সমস্ত / লুপের জন্য প্রদর্শিত হবে না।
এ লেভি

আমার জন্য এই jQuery ভেঙেছে এর মতো অবজেক্ট প্রোটোটাইপে যুক্ত করা। এমনকি যখন আমি ক্লোন 2 নামকরণ করেছি।
আইপ্যাডডিফলার ২০১১ ২১

3
@ আইপ্যাডডিভোপার ২০১১১ উপরের কোডটিতে একটি বাগ ছিল যেখানে এটি '(' আমি এর জন্য) এর পরিবর্তে '(এটিতে আমি এর জন্য)' 'না করে একটি বৈশ্বিক পরিবর্তনশীল তৈরি করে। আমার সম্পাদনা করার যথেষ্ট কর্ম আছে এবং এটি ঠিক করেছিলাম এবং তাই করেছিলাম।
মাইকম্যাকানা

1
@ ক্যালভিন: এটি একটি অগণনীয় সম্পত্তি তৈরি করা উচিত, অন্যথায় 'ক্লোন' 'লুপের জন্য' উপস্থিত হবে।
মাইকমেকানা

2
কেন var copiedObj = Object.create(obj);দুর্দান্ত উপায় না ?
ড্যান পি।

19

ES-6 এ আপনি কেবল অবজেক্ট.সেসাইন (...) ব্যবহার করতে পারেন। উদা:

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

একটি ভাল রেফারেন্স এখানে: https://googlechrome.github.io/sample/object-assign-es6/


12
এটি বস্তুর গভীর ক্লোন করে না।
আগস্ট

এটি একটি অ্যাসাইনমেন্ট, কোনও অনুলিপি নয়। ক্লোন.টাইটেল = "কেবলমাত্র একটি ক্লোন" এর অর্থ হ'ল .জটাইটেল = "কেবল একটি ক্লোন"।
হোল্ডঅফহাঙ্গার

@ হোল্ডঅফ হ্যাঞ্জার আপনার ব্রাউজারের জেএস কনসোলে এটি পরীক্ষা করুন ( let obj = {person: 'Thor Odinson'}; let clone = Object.assign({}, obj); clone.title = "Whazzup";)
কলস্পার

@ কল্লাপার: এটি আমি যা যাচাই করেছিলাম ঠিক সেটাই, তবে কনসোল.লগ (ব্যক্তি) "থার ওডিনসন" নয়, "ওয়াজআপ" হবে। আগস্ট এর মন্তব্য দেখুন।
হোল্ডঅফহ্যাঙ্গার

1
@ হোল্ডঅফ হুঙ্গার ক্রোম 60.0.3112.113 বা এজতে 14.14393 তে ঘটে না; আগামের মন্তব্য প্রমিতের ধরণের objসম্পত্তিগুলির মানগুলি ক্লোন করা হওয়ায় প্রয়োগ হয় না । সম্পত্তির মানগুলি যা অবজেক্টস সেগুলি ক্লোন করা হবে না।
কলস্পার

18

ECMAScript 2018 এ

let objClone = { ...obj };

সচেতন হন যে নেস্টেড অবজেক্টগুলি এখনও রেফারেন্স হিসাবে অনুলিপি করা হয়েছে।


1
ইঙ্গিতটির জন্য ধন্যবাদ যে নেস্টেড অবজেক্টগুলি এখনও রেফারেন্স হিসাবে অনুলিপি করা হয়েছে! আমার কোডটি ডিবাগ করার সময় আমি প্রায় পাগল হয়ে গিয়েছিলাম কারণ আমি "ক্লোন" এর নেস্টেড বৈশিষ্ট্যগুলি পরিবর্তন করেছি তবে আসলটি সংশোধন হয়েছে।
বেনি নিউজবাউয়ার

এটি 2018 নয়, ES2016, এবং এই উত্তরটি দুই বছর আগে দেওয়া হয়েছিল
ড্যান ড্যাসক্লেস্কু

সুতরাং আমি যদি নেস্টেড সম্পত্তির অনুলিপিও চাই তবে কী হবে
সুনীল গারগ

1
@ সুনিলগার্গ নেস্টেড সম্পত্তি অনুলিপি করতে পাশাপাশি const objDeepClone = JSON.parse(JSON.stringify(obj));
আপনিও

16

লোডাশ ব্যবহার:

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

5
ওএমজি এটি ক্লোনিং পুনরায় উদ্ভাবন করা উন্মাদ হবে। এটিই একমাত্র বুদ্ধিমান উত্তর।
ড্যান রস

5
আমি পছন্দ করি _.cloneDeep(x)এটি মূলত উপরের মতো একই জিনিস, তবে আরও ভাল করে পড়া।
garbanzio

14

খুব সুন্দর - সাধারণ।
ম্যাট এইচ

@ ম্যাথঃ এই উত্তরটি ইতিমধ্যে ২০১২ সালে দেওয়া হয়েছিল । তুমি এটা দেখেছিলে? মোহাম্মদ, আপনি কি তার একটির সদৃশ করার আগে বিদ্যমান উত্তরগুলি পরীক্ষা করেছেন?
ড্যান ড্যাসক্লেস্কু

ভালভাবে একটি উপায়। ty কখনই সে সম্পর্কে
ভাবেনি

13

আপনি কোনও বস্তুর ক্লোন করতে পারেন এবং কোডের একক লাইন ব্যবহার করে পূর্ববর্তীটি থেকে কোনও রেফারেন্স সরিয়ে ফেলতে পারেন। সহজভাবে করুন:

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

ব্রাউজার / ইঞ্জিনগুলির জন্য যা বর্তমানে অবজেক্ট.ক্রিট সমর্থন করে না আপনি এই পলিফিলটি ব্যবহার করতে পারেন:

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

1
+1 Object.create(...)অবশ্যই যাওয়ার উপায় মনে হচ্ছে।
রেনি নিফেনিগার

নিখুঁত উত্তর. আপনি জন্য একটি ব্যাখ্যা যোগ করতে পারে Object.hasOwnProperty? এইভাবে লোকেরা কীভাবে প্রোটোটাইপ লিঙ্কটি অনুসন্ধান করা রোধ করতে পারে তা জানেন।
ব্যাঙবাঁধে

ভাল কাজ করে তবে পলিফিল কোন ব্রাউজারগুলিতে কাজ করে?
ইয়ান লুন

11
এটি প্রোটোটাইপ হিসাবে এটি একটি ওজেক্ট 1 দিয়ে অজেক্ট 2 তৈরি করছে। এটি কেবলমাত্র কাজ করে কারণ আপনি textসদস্যটিকে ওজেজ 2 এ ছায়া দিচ্ছেন। আপনি কোনও অনুলিপি তৈরি করছেন না, কেবল প্রজোটাইপ শৃঙ্খলে পিছিয়ে দিচ্ছেন যখন সদস্য 2 ওজেজে পাওয়া যায় না।
নিক দেশালিউনার্স 21

2
এটি এটিকে "রেফারেন্স ছাড়াই" তৈরি করে না, এটি কেবল প্রোটোটাইপটিতে রেফারেন্সটি স্থানান্তর করে। এটি এখনও একটি রেফারেন্স। যদি কোনও সম্পত্তি আসল পরিবর্তিত হয় তবে "ক্লোন" এর প্রোটোটাইপ সম্পত্তিও থাকবে। এটি মোটেই ক্লোন নয়।
জিম্বো জনি

13

পুরানো প্রশ্নের নতুন উত্তর! আপনার যদি স্প্রেড সিনট্যাক্সের সাথে ECMAScript 2016 (ES6) ব্যবহার করার আনন্দ হয় তবে এটি সহজ।

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

এটি কোনও অবজেক্টের অগভীর কপির জন্য একটি পরিষ্কার পদ্ধতি সরবরাহ করে। একটি গভীর অনুলিপি তৈরি করা, যার অর্থ প্রতিটি পুনরাবৃত্তভাবে নেস্ট করা বস্তুতে প্রতিটি মানের একটি নতুন কপি ম্যাকগিন করা, উপরের ভারী সমাধানগুলির প্রয়োজন।

জাভাস্ক্রিপ্ট বিকশিত হয়।


2
আপনি ফাংশন বস্তুর উপর সংজ্ঞায়িত আছে এটা কাজ করে না
পেত্র Marek

যতদূর আমি দেখছি স্প্রেড অপারেটর কেবল পুনরাবৃত্তদের সাথেই কাজ করে - ডেভেলপার.মোজিলা.আরোগ বলেছেন: var obj = {'key1': 'value1'}; var array = [...obj]; // TypeError: obj is not iterable
ওলেহ

@ ওলেহ তাই [...
আপত্তি

@ মানিকান্তগৌতম আমি আগে অবজেক্ট.সেসাইন () ব্যবহার করছিলাম তবে এখন প্রকৃতপক্ষে ক্রোম, ফায়ারফক্স (এখনও এজ এবং সাফারিতে নেই) তে অবজেক্ট স্প্রেড সিনট্যাক্স সমর্থিত। এটির ইসমাস্ক্রিপ্ট প্রস্তাব ... তবে বাবেল যতদূর আমি দেখতে পাচ্ছি এটি সমর্থন করে, সম্ভবত এটি ব্যবহার করা নিরাপদ।
ওলেহ

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

ES6 সমাধানটি যদি আপনি (অগভীর) ক্লাস উদাহরণটি ক্লোন করতে চান তবে কেবল কোনও সম্পত্তি বস্তু নয়।


এটি কীভাবে আলাদা let cloned = Object.assign({}, obj)?
ceztko

10

আমি মনে করি একটি সহজ এবং কার্যকরী উত্তর আছে। গভীর অনুলিপিটিতে দুটি উদ্বেগ রয়েছে:

  1. সম্পত্তি একে অপরের কাছে স্বাধীন রাখুন।
  2. এবং ক্লোনড অবজেক্টে পদ্ধতিগুলিকে জীবিত রাখুন।

সুতরাং আমি মনে করি একটি সহজ সমাধান হ'ল প্রথমে সিরিয়ালাইজ করা এবং ডিজিটালাইজ করা এবং তারপরে ফাংশনগুলি অনুলিপি করার জন্য এটিতে একটি কার্য সম্পাদন করা।

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

যদিও এই প্রশ্নের অনেক উত্তর রয়েছে, আমি আশা করি এটির একটিও সহায়তা করবে।


যদিও আমাকে লড্যাশ আমদানি করার অনুমতি দেওয়া হলেও আমি লোডাশ ব্যবহার পছন্দ করি cloneDeep
পরিচালিত

2
আমি JSON.parse (JSON.stringify (উত্স)) ব্যবহার করছি। সর্বদাই কাজ করছে.
মিশা

2
@ মিশা, এইভাবে আপনি কার্যগুলি মিস করবেন। শব্দ 'ওয়ার্কস' এর অনেক অর্থ রয়েছে।
কনডাক্টক্লাইভার

এবং মনে রাখবেন যে, আমি যেভাবে উল্লেখ করেছি, কেবলমাত্র প্রথম স্তরটির কাজগুলি অনুলিপি করা হবে। সুতরাং আমরা যদি একে অপরের ভিতরে কিছু অবজেক্টস থাকে, তবে একমাত্র উপায় হ'ল পুনরাবৃত্তিভাবে ক্ষেত্রের মাধ্যমে ক্ষেত্রটি অনুলিপি করা।
কনডাক্টক্লাইভার

9

একটি গভীর অনুলিপি এবং ক্লোনটির জন্য, JSON.stringify করুন এবং তারপরে JSON. অংশটি ভাগ করুন:

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

বেশ চালাক ... এই পদ্ধতির কোনও ডাউনসাইড?
Aleks

8

এটি ফাংশন এবং একাধিক / চক্রীয় রেফারেন্সগুলির ক্লোনিং পরিচালনা করতে এ লেভির কোডের একটি রূপান্তর - এর অর্থ কী যে গাছের দুটি বৈশিষ্ট্য যা ক্লোন করা হয় একই বস্তুর রেফারেন্স হলে ক্লোনযুক্ত বস্তু গাছের এইগুলি থাকবে বৈশিষ্ট্যগুলি রেফারেন্স করা বস্তুর এক এবং একই ক্লোনিকে নির্দেশ করে। এটি চক্রীয় নির্ভরতাগুলির ক্ষেত্রেও সমাধান করে, যা যদি হাতছাড়া করে ফেলে রাখা হয় তবে অসীম লুপের দিকে নিয়ে যায়। অ্যালগরিদমের জটিলতা হ'ল হে (এন)

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

কিছু দ্রুত পরীক্ষা

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

1
২০১ September সালের সেপ্টেম্বর পর্যন্ত এই প্রশ্নের একমাত্র সঠিক সমাধান।
ডোমকিউ

6

আমি শুধু সমস্ত যোগ করতে চেয়েছিলেন Object.create এই পোস্টের সমাধানগুলিতে , এটি নোডেজগুলি দিয়ে কাঙ্ক্ষিত উপায়ে কাজ করে না।

ফায়ারফক্সে ফলাফল

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

হয়

{test:"test"}

নোডেজে এটি হয়

{}

এটি প্রোটোটাইপাল উত্তরাধিকার, ক্লোনিং নয়।
d13

1
@ d13 আপনার আর্গুমেন্টটি বৈধ থাকাকালীন নোট করুন যে কোনও জাতির ক্লোন করার জাভাস্ক্রিপ্টে কোনও মানক উপায় নেই। এটি প্রোটোটাইপিকাল উত্তরাধিকার, তবে ধারণাগুলি বুঝতে পারলেও এটি ক্লোন হিসাবে ব্যবহার করা যেতে পারে।
ব্যাঙবাড়ী

@froginvasion। অবজেক্ট.ক্রিয়েট ব্যবহারের ক্ষেত্রে একমাত্র সমস্যা হ'ল নেস্টেড অবজেক্টস এবং অ্যারেগুলি কেবল প্রোটোটাইপের নেস্টেড অবজেক্ট এবং অ্যারেগুলির পয়েন্টার রেফারেন্স। jsbin.com/EKivInO/2/edit?js,console । প্রযুক্তিগতভাবে একটি "ক্লোন করা" অবজেক্টের নিজস্ব অনন্য বৈশিষ্ট্য থাকতে হবে যা অন্য সামগ্রীর বৈশিষ্ট্যের সাথে ভাগ করে নেওয়া হয় না।
d13

@ d13 ঠিক আছে, আমি এখন আপনার পয়েন্ট দেখুন। তবে আমি যা বোঝাতে চেয়েছি তা হল যে প্রচুর লোক প্রোটোটাইপিকাল উত্তরাধিকারের ধারণার সাথে বিচ্ছিন্ন হয়ে পড়েছে এবং এটি কীভাবে কাজ করে তা শিখতে আমার কাছে ব্যর্থ হয়। আমি যদি ভুল না হয়ে থাকি তবে আপনার উদাহরণটি কেবল Object.hasOwnPropertyঅ্যারের মালিকানাধীন কিনা তা পরীক্ষা করে কল করে ঠিক করা যেতে পারে । হ্যাঁ এটি প্রোটোটাইপিকাল উত্তরাধিকার মোকাবেলায় অতিরিক্ত জটিলতা যুক্ত করে।
ব্যাঙবাঁধের

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

2
if(!src && typeof src != "object"){। আমি মনে করি এটি হওয়া উচিত ||নয় &&
মাইকেএম

6

যেহেতু মাইন্ডেভোর বলেছে যে ক্লোন করা বস্তুটি 'আক্ষরিক-নির্মিত' অবজেক্ট, তাই সমাধানটি হ'ল বস্তুর উদাহরণকে ক্লোনিংয়ের পরিবর্তে একাধিকবার উত্পন্ন করা যেতে পারে :

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

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

6

আমি আমার নিজস্ব বাস্তবায়ন লিখেছি। এটি আরও ভাল সমাধান হিসাবে গণ্য হয়েছে কিনা তা নিশ্চিত নন:

/*
    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)    /
*/

নিম্নলিখিত বাস্তবায়ন:

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

আমার বিষয়টির জন্য কাজ করছি না, যদিও আমার মামলাটি কিছুটা জটিল।
সাজুউক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.