একটি জাভাস্ক্রিপ্ট ES6 শ্রেণীর উদাহরণটি কীভাবে ক্লোন করবেন


96

আমি কীভাবে ES6 ব্যবহার করে জাভাস্ক্রিপ্ট ক্লাসের উদাহরণ ক্লোন করব।

আমি jquery বা $ প্রসারিত উপর ভিত্তি করে সমাধানগুলিতে আগ্রহী নই।

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

সম্পাদনা করুন: পরামর্শ দেওয়া হচ্ছে যে আমার প্রশ্নটি একটি সদৃশ; আমি উত্তরটি দেখেছি কিন্তু এটি 7 বছরের পুরানো এবং প্রি ES6 জেএস ব্যবহার করে খুব জটিল উত্তর জড়িত। আমি প্রস্তাব দিচ্ছি যে আমার প্রশ্নটি, যা ES6 এর জন্য মঞ্জুরি দেয়, এর একটি নাটকীয়ভাবে সহজ সমাধান রয়েছে।


4
স্ট্যাক ওভারফ্লোতে যদি আপনার কোনও পুরানো প্রশ্নের জন্য নতুন উত্তর থাকে তবে দয়া করে মূল প্রশ্নের উত্তরটি যুক্ত করুন, কেবল একটি নতুন উত্তর তৈরি করবেন না।
হেরেটিক বানর

4
আমি দেখতে পাচ্ছি টম যে সমস্যার মুখোমুখি হচ্ছে / যেহেতু ইএস class শ্রেণীর দৃষ্টান্তগুলি "নিয়মিত" অবজেক্ট থেকে আলাদা কাজ করে।
চেরিনার্ড

4
এছাড়াও, গৃহীত উত্তরের কোডের প্রথম টুকরোটি আপনার "সম্ভাব্য নকল" আসলে ক্র্যাশ সরবরাহ করে যখন আমি কোনও ES6 শ্রেণীর উদাহরণ দিয়ে চালানোর চেষ্টা করি
চেরিনার্ড

আমি মনে করি এটি একটি সদৃশ নয়, কারণ যদিও ES6 শ্রেণীর উদাহরণটি একটি বস্তু, প্রতিটি বস্তু ES6 শ্রেণীর উদাহরণ নয় এবং তাই অন্য প্রশ্নটি এই প্রশ্নের ইস্যুটিকে সম্বোধন করে না।
টোমা জ্যাটো - মনিকা

4
এটি কোনও সদৃশ নয়। অন্য প্রশ্নটি Objectতথ্য ধারক হিসাবে ব্যবহৃত খাঁটি সম্পর্কে ছিল । এটি এক ES6 classএস সম্পর্কে এবং শ্রেণীর ধরণের তথ্য না হারাতে সমস্যা। এটির আলাদা সমাধান দরকার।
ফ্লোরি

উত্তর:


111

এটা জটিল; আমি অনেক চেষ্টা করেছিলাম! শেষ পর্যন্ত, এই ওয়ান-লাইনারটি আমার কাস্টম ES6 শ্রেণীর উদাহরণগুলির জন্য কাজ করেছে:

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

এটি প্রোটোটাইপ সেট করা এড়ায় কারণ তারা বলে যে এটি কোডটি অনেকটা ধীর করে দেয়।

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

উপসংহার: এটি একটি গণ্ডগোল। আসুন আশা করি যে একদিন দেশীয় এবং পরিষ্কার ক্লোন কার্যকারিতা থাকবে।


4
এটি স্থিতিশীল পদ্ধতিগুলি অনুলিপি করবে না কারণ তারা প্রকৃতপক্ষে গণনার নিজস্ব সম্পত্তি নয়।
মিঃ লাভালাম্প

4
@ মিঃ লাভালাম্প এবং কীভাবে আপনি স্থির পদ্ধতিগুলি অনুলিপি করতে পারেন (এছাড়াও)?
ফ্লোরি

এই অ্যারে ধ্বংস হবে! এটি "0", "1", ... কীগুলির সাহায্যে সমস্ত অ্যারেগুলিকে বস্তুতে রূপান্তরিত করবে।
ওয়াহিদ

4
@ কেশা অ্যান্টনভ আপনি টাইপফ এবং অ্যারে পদ্ধতিগুলির সাহায্যে সমাধান পেতে সক্ষম হতে পারেন। আমি নিজে নিজে সমস্ত সম্পত্তি ক্লোন করতে পছন্দ করেছিলাম to
ওয়াহিদ

4
এটি নিজেরাই বস্তুযুক্ত
jduhls

10
const clone = Object.assign( {}, instanceOfBlah );
Object.setPrototypeOf( clone, Blah.prototype );

অবজেক্ট.সেসাইন এর বৈশিষ্ট্যগুলি নোট করুন : এটি অগভীর অনুলিপি করে এবং শ্রেণি পদ্ধতিগুলি অনুলিপি করে না।

আপনি যদি একটি অনুলিপি বা অনুলিপিটির উপর আরও নিয়ন্ত্রণ চান তবে লড্যাশ ক্লোন ফাংশন রয়েছে


4
যেহেতু Object.createনির্দিষ্ট প্রোটোটাইপ, কেন না তারপর সাথে নতুন বস্তু সৃষ্টি const clone = Object.assign(Object.create(instanceOfBlah), instanceOfBlah)। ক্লাসের পদ্ধতিগুলিও অনুলিপি করা হবে।
বরবটাস

4
@ বারব্যাটাস যা ভুল প্রোটোটাইপ ব্যবহার করে যদিও Blah.prototype != instanceOfBlah,। আপনার ব্যবহার করা উচিতObject.getPrototypeOf(instanceOfBlah)
বার্গি

4
@ বেরগি নং, ES6 শ্রেণীর উদাহরণের সর্বদা প্রোটোটাইপ থাকে না। কোডেপেন.ইও / টেকনিউক / স্পেন / কেডিজেডজেম পরীক্ষা করে দেখুন যে এটি উদাহরণের সাথেও কাজ করে।
বারব্যাটাস

@ বারব্যাটাস দুঃখিত, কি? আমি অনুসরণ করি না সমস্ত দৃষ্টান্তের একটি প্রোটোটাইপ থাকে, এটাই তাদের উদাহরণ দেয়। ফ্লোরির উত্তর থেকে কোডটি চেষ্টা করে দেখুন।
বার্গি

4
@ বার্গি আমার ধারণা এটি বাবেল কনফিগারেশন বা কোনও কিছুর উপর নির্ভর করে। আমি এখনই একটি প্রতিক্রিয়াশীল নেটিভ অ্যাপ্লিকেশন বাস্তবায়ন করছি এবং উত্তরাধিকার সূত্রে প্রাপ্ত কোনও সম্পত্তি সহ দৃষ্টান্তগুলির প্রোটোটাইপ নালাগুলি নেই। এছাড়াও আপনি এখানে দেখতে পাবেন ডেভেলপার.মোজিলা.আর.ইন- ইউএস / ডকস / ওয়েবে / জাভা স্ক্রিপ্ট / রেফারেন্স / it'sএই সম্ভব যে getProotypeOf নালার প্রত্যাবর্তন করে।
বারব্যাটাস

3

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

জাভাস্ক্রিপ্টে অবজেক্টগুলি ক্লোন করার জন্য কোনও সহজ বা সোজা উপায় নেই। "অগভীর অনুলিপি" ব্যবহার করে এখানে প্রথম উদাহরণ দেওয়া হয়েছে:

1 -> অগভীর ক্লোন:

class Employee {
    constructor(first, last, street) {
        this.firstName = first;
        this.lastName = last;
        this.address = { street: street };
    }

    logFullName() {
        console.log(this.firstName + ' ' + this.lastName);
    }
}

let original = new Employee('Cassio', 'Seffrin', 'Street A, 23');
let clone =  Object.assign({},original); //object.assing() method
let cloneWithPrototype Object.create(Object.getPrototypeOf(original)), original) //  the clone will inherit the prototype methods of the original.
let clone2 = { ...original }; // the same of object assign but shorter sintax using "spread operator"
clone.firstName = 'John';
clone.address.street = 'Street B, 99'; //will not be cloned

ফলাফল:

আসল.লগ ফুলনাম ():

ফলাফল: ক্যাসিও সেফরিন

ক্লোন.লগ ফুলনাম ():

ফলাফল: জন সেফরিন

original.address.street;

ফলাফল: 'স্ট্রিট বি, 99' // লক্ষ্য করুন যে আসল সাব অবজেক্টটি পরিবর্তন করা হয়েছিল

বিজ্ঞপ্তি: উদাহরণটির নিজস্ব বৈশিষ্ট্য হিসাবে ক্লোজারগুলি থাকলে এই পদ্ধতিটি এটি মোড়বে না। ( ক্লোজারগুলি সম্পর্কে আরও পড়ুন ) এবং আরও, সাব অবজেক্ট "ঠিকানা" ক্লোন হবে না।

ক্লোন.লগ ফুলনাম ()

কাজ করবে না.

ক্লোনওয়েথপ্রোটোটাইপ.লগ ফুলনাম ()

কাজ করবে, কারণ ক্লোনটি এর প্রোটোটাইপগুলিও অনুলিপি করবে।

অবজেক্ট.সেসাইন দিয়ে অ্যারেগুলি ক্লোন করতে:

let cloneArr = array.map((a) => Object.assign({}, a));

ECMAScript স্প্রেড সিনট্যাক্স ব্যবহার করে ক্লোন অ্যারে:

let cloneArrSpread = array.map((a) => ({ ...a }));

2 -> গভীর ক্লোন:

সম্পূর্ণ নতুন অবজেক্ট রেফারেন্স সংরক্ষণাগার করতে আমরা JSON.stringify () ব্যবহার করতে পারি মূল স্ট্রিংটিকে পার্সিং হিসাবে এবং পার্স করার পরে এটি JSON.parse () এ ফিরে আসে।

let deepClone = JSON.parse(JSON.stringify(original));

গভীর ক্লোন দিয়ে ঠিকানার রেফারেন্স রাখা হবে। তবে ডিপক্লোন প্রোটোটাইপগুলি ছেড়ে দেওয়া হবে, সুতরাং ডিপক্লোন.লগ ফুলনাম () কাজ করবে না।

3 -> তৃতীয় পক্ষের গ্রন্থাগারগুলি:

আর একটি বিকল্প লোড্যাশ বা আন্ডারস্কোরের মতো তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করবে। তারা একটি নতুন অবজেক্ট তৈরি করবে এবং প্রতিটি মানটিকে মূল থেকে নতুন অবজেক্টে তার রেফারেন্সগুলিকে স্মরণে রাখবে।

অ্যান্ডস্কোর: যাক ক্লোনআউন্ডারস্কোর = _ (মূল) .ক্লোন ();

লোড্যাশ ক্লোন: var ক্লোনলোডাশ = _ক্লোনডিপ (আসল);

লোড্যাশ বা আন্ডারস্কোরের ডাউনসাইডটি আপনার প্রকল্পে কিছু অতিরিক্ত গ্রন্থাগার অন্তর্ভুক্ত করার দরকার ছিল। তবে তারা ভাল বিকল্প এবং উচ্চ কর্মক্ষমতা ফলাফল উত্পাদন করে।


4
অ্যাসাইন করার সময় {}, ক্লোনটি আসলটির কোনও প্রোটোটাইপ পদ্ধতির উত্তরাধিকারী হবে না। clone.logFullName()কিছুতেই কাজ করবে না। Object.assign( Object.create(Object.getPrototypeOf(eOriginal)), eOriginal)আপনি আগে ছিল জরিমানা করেছে, কেন তুমি যে পরিবর্তন হয়নি?
বার্গি

4
@ বার্গি আপনার অবদানের জন্য ধন্যবাদ জানায়, আমি এখনই আমার উত্তরটি সম্পাদনা করছি, আমি প্রোটোটাইপগুলি অনুলিপি করতে আপনার পয়েন্টটি যুক্ত করেছি!
ক্যাসিও সেফরিন

4
আমি @ বার্গি আপনার সাহায্যের প্রশংসা করি, দয়া করে এখন আপনার মতামত দিন। আমি সংস্করণ শেষ করেছি। আমার মনে হয় এখন উত্তরটি প্রায় সমস্ত প্রশ্নকে coveredেকে ফেলেছে। কথা!
ক্যাসিও সেফরিন

4
হ্যাঁ, এবং ঠিক যেমন Object.assign({},original), এটি কাজ করে না।
বার্গি

4
কখনও কখনও সহজ পদ্ধতির সমস্ত প্রয়োজন আমাদের। আপনার যদি প্রোটোটাইপগুলির প্রয়োজন না হয় এবং জটিল অবজেক্টগুলি কেবল "ক্লোন = = {... আসল}" সমস্যার সমাধান করতে পারে
ক্যাসিও সেফরিন

0

অন্য একটি লাইনার:

বেশিরভাগ সময় ... (তারিখ, রেজেক্সট, মানচিত্র, স্ট্রিং, নম্বর, অ্যারের জন্য কাজ করে), বিটিডাব্লু, ক্লোনিং স্ট্রিং, সংখ্যাটি কিছুটা মজার।

let clone = new obj.constructor(...[obj].flat())

অনুলিপি নির্মাণকারী ছাড়াই class শ্রেণীর জন্য:

let clone = Object.assign(new obj.constructor(...[obj].flat()), obj)

0
class A {
  constructor() {
    this.x = 1;
  }

  y() {
    return 1;
  }
}

const a = new A();

const output = Object.getOwnPropertyNames(Object.getPrototypeOf(a)).concat(Object.getOwnPropertyNames(a)).reduce((accumulator, currentValue, currentIndex, array) => {
  accumulator[currentValue] = a[currentValue];
  return accumulator;
}, {});

এখানে চিত্র বর্ণনা লিখুন


-4

আপনি স্প্রেড অপারেটর ব্যবহার করতে পারেন, উদাহরণস্বরূপ যদি আপনি ওবজ নামের কোনও বস্তুর ক্লোন করতে চান:

let clone = { ...obj};

এবং আপনি যদি ক্লোন করা বস্তুটিতে কোনও কিছু পরিবর্তন করতে বা যোগ করতে চান:

let clone = { ...obj, change: "something" };
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.