একটি ভেরিয়েবলের মান অন্যটিতে অনুলিপি করুন


102

আমার একটি ভেরিয়েবল রয়েছে যার মান হিসাবে JSON অবজেক্ট রয়েছে। আমি সরাসরি এই ভেরিয়েবলটি অন্য কয়েকটি ভেরিয়েবলের কাছে বরাদ্দ করি যাতে তারা একই মান ভাগ করে দেয়। এটা এভাবে কাজ করে:

var a = $('#some_hidden_var').val(),
    b = a;

এটি কাজ করে এবং উভয়ের একই মান রয়েছে। আমি আমার অ্যাপের মাধ্যমে mousemoveআপডেট করতে ইভেন্ট হ্যান্ডলারটি ব্যবহার করি use bএকটি বাটন ক্লিক করুন, আমি রূপে ফিরিয়ে নিয়ে যেতে চান bমূল মান, সঞ্চিত মান অর্থ a

$('#revert').on('click', function(e){
    b = a;
});

এর পরে যদি আমি একই mousemoveইভেন্ট হ্যান্ডলারটি ব্যবহার করি তবে এটি উভয়ই আপডেট হয় aএবং bআগে যখন এটি কেবল bপ্রত্যাশিত আপডেট হয় ।

আমি এই ইস্যুতে স্টাম্পড! এখানে কি ভুল?


দয়া করে আপনার মাউসমেভ হ্যান্ডলারটি দেখান। এছাড়াও, দেওয়া aথেকে .val()আমি সেট করে ধরে নিয়েছি এটি JSON (একটি স্ট্রিং), কোনও বস্তু নয় - এটি কি ঠিক? আপনি কি JSON.parse(a)কোনও মুহুর্তে আসল অবজেক্টটি পেতে ব্যবহার করেন?
nnnnnn

হ্যাঁ এটি একটি স্ট্রিং তবে আমি $.parseJSONএটিকে কোনও বস্তুতে রূপান্তর করতে ব্যবহার করি । গঠন: { 'key': {...}, 'key': {...}, ...}। দুঃখিত এখানে কোনও কোড পোস্ট করতে পারবেন না, আমার কর্মক্ষেত্রে অনুমোদিত নয়!
রটউইক গাঙ্গুরদে

4
সুতরাং aএকটি বস্তু হয়?
আরমান্ড

4
মনে হচ্ছে কোনও স্কোপিং ইস্যু .. aএকটি বিশ্বব্যাপী পরিবর্তনশীল?
মাস্টার্দি

4
আপনি যে কোডটি দেখিয়েছেন তাতে কেবল স্ট্রিং রয়েছে। আপনি যদি অবজেক্টের সাথে কথা বলছেন তবে একাধিক ভেরিয়েবল একই বস্তুর উল্লেখ করতে পারে এবং যাতে সেই বস্তুটি কোনও ভেরিয়েবলের মাধ্যমে পরিবর্তিত হতে পারে। সুতরাং ভেরিয়েবলগুলি পরিচালনা করে এমন কোডের আরও বেশি কিছু না দেখে (এটি কোথায় আসে $.parseJSON()?) সমস্যাটি কী তা বলা শক্ত। আপনার কর্মক্ষেত্রের নিয়মাবলী সম্পর্কে, আপনাকে আপনার আসল কোডটি সম্পূর্ণ পোস্ট করতে হবে না, কেবল সমস্যাটি প্রদর্শন করে এমন একটি সংক্ষিপ্ত এবং আরও সাধারণ উদাহরণ নিয়ে আসা উচিত (এবং, আদর্শভাবে, jsfiddle.net এ একটি লাইভ ডেমোর লিঙ্ক অন্তর্ভুক্ত ) ।
nnnnnn

উত্তর:


205

=জাভাস্ক্রিপ্টে অপারেটর কী করবে এবং কী করবে না তা বোঝা গুরুত্বপূর্ণ ।

=অপারেটর একটি দেখা যায় না কপি ডেটার।

=অপারেটর একটি নতুন সৃষ্টি রেফারেন্স থেকে একই তথ্য।

আপনি আপনার মূল কোডটি চালানোর পরে:

var a = $('#some_hidden_var').val(),
    b = a;

aএবং একই বস্তুরb জন্য এখন দুটি পৃথক নাম ।

এই অবজেক্টের বিষয়বস্তুগুলিতে আপনি যে কোনও পরিবর্তন করেন তবে আপনি এটি aপরিবর্তনশীল বা ভেরিয়েবলের মাধ্যমে উল্লেখ করেছেন কিনা তা একইভাবে দেখা যাবে b। তারা একই জিনিস।

সুতরাং, পরে যখন আপনি এই কোডটি দিয়ে bআসল aঅবজেক্টে "প্রত্যাবর্তন" করার চেষ্টা করবেন :

b = a;

কোডটি আসলে কিছুই করে না , কারণ aএবং bহুবহু একই জিনিস। কোডটি সমান যেমন আপনি লিখেছেন:

b = b;

যা অবশ্যই কিছু করবে না।

আপনার নতুন কোডটি কেন কাজ করে?

b = { key1: a.key1, key2: a.key2 };

এখানে আপনি {...}বস্তুর আক্ষরিক সাথে একেবারে নতুন অবজেক্ট তৈরি করছেন । এই নতুন অবজেক্টটি আপনার পুরানো অবজেক্টের মতো নয়। সুতরাং আপনি এখন bএই নতুন অবজেক্টের রেফারেন্স হিসাবে সেট করছেন যা আপনি যা চান তা করে।

যেকোন স্বেচ্ছাচারিত বস্তু পরিচালনা করতে আপনি কোনও বস্তুর ক্লোনিং ফাংশন যেমন আরমান্ডের উত্তরে তালিকাভুক্ত হিসাবে ব্যবহার করতে পারেন বা আপনি jQuery ব্যবহার করছেন কেবলমাত্র $.extend()ফাংশনটি ব্যবহার করুন । এই ফাংশনটি কোনও অগভীর অনুলিপি বা কোনও সামগ্রীর গভীর অনুলিপি তৈরি করবে। (এটি কোনও $().clone()পদ্ধতির সাথে বিভ্রান্ত করবেন না যা কোনও ডিওএম উপাদানগুলি অনুলিপি করার জন্য, বস্তুর জন্য নয়))

অগভীর কপির জন্য:

b = $.extend( {}, a );

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

b = $.extend( true, {}, a );

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

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

var obj = {
    w: 123,
    x: {
        y: 456,
        z: 789
    }
};

আপনি যদি সেই অবজেক্টের অগভীর অনুলিপি করেন তবে xআপনার নতুন অবজেক্টের সম্পত্তিটি xমূল থেকে একই জিনিস:

var copy = $.extend( {}, obj );
copy.w = 321;
copy.x.y = 654;

এখন আপনার অবজেক্টগুলি এর মতো দেখতে পাবেন:

// copy looks as expected
var copy = {
    w: 321,
    x: {
        y: 654,
        z: 789
    }
};

// But changing copy.x.y also changed obj.x.y!
var obj = {
    w: 123,  // changing copy.w didn't affect obj.w
    x: {
        y: 654,  // changing copy.x.y also changed obj.x.y
        z: 789
    }
};

আপনি এটিকে একটি অনুলিপি সহ এড়াতে পারবেন। গভীর অনুলিপি প্রতিটি নেস্টেড অবজেক্ট এবং অ্যারেতে (এবং তারিখটি আর্ম্যান্ডের কোডে) পুনরাবৃত্তি করে সেইভাবে এই জিনিসগুলির অনুলিপি তৈরি করতে শীর্ষ স্তরের বস্তুর অনুলিপি তৈরি করে। সুতরাং পরিবর্তন copy.x.yপ্রভাবিত করবে না obj.x.y

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


ধন্যবাদ, আমি এটিই খুঁজছিলাম এটিকে ঘিরে কাজ করার কোনও উপায়? আমার বর্তমান পরিস্থিতিতে, এটি ঠিক করা সহজ ছিল যেহেতু আমার কাছে মাত্র 2 টি সম্পত্তি ছিল। তবে বড় আকারের বস্তু থাকতে পারে।
রটউইক গাঙ্গুরদে

4
আরমান্ডের উত্তরে একটি অবজেক্ট ক্লোন ফাংশন রয়েছে যা কৌশলটি করবে। বা যেহেতু আপনি jQuery ব্যবহার করছেন তাই আপনি অন্তর্নির্মিত $.extend()ফাংশনটি ব্যবহার করতে পারেন । উপরে বিবরণ। :-)
মাইকেল গ্যারি

মাইকেল এর দুর্দান্ত ব্যাখ্যা!
রটউইক গাঙ্গুরদে

8
@ মিশেলগিয়ারি এটি নিটপিকিং হতে পারে তবে নিয়মটি কেবলমাত্র বস্তুগুলিতে প্রয়োগ হয় না এবং আদিম পরিবর্তনশীল নয়? উত্তরে এটি লক্ষণীয় মূল্যবান
জোনাথন ডস সান্টোস

এই জাতীয় সমাধান Armands উত্তরে মত মাইকেল গিয়েরি বলেন =।
AlexanderGriffin

57

আমি JSON এর কাজগুলি ব্যবহার করে দেখতে পেলাম তবে আমাদের বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সগুলির জন্য দেখুন

var newInstance = JSON.parse(JSON.stringify(firstInstance));

4
আমি বুঝতে পারি এটি কিছুটা দেরি হয়েছে, তবে এই পদ্ধতিতে কোনও সমস্যা আছে? দেখে মনে হচ্ছে এটি প্রথম চেষ্টা করে আশ্চর্যজনকভাবে কাজ করে।
ম্যানকিন্ড 1023

4
এটি প্রায় প্রতিটি পরিস্থিতিতে দুর্দান্ত is উদাহরণস্বরূপ কয়েকটি কোড: let a = {}; let b = {a:a}; a.b = b; JSON.stringify(a)একটি
টাইপরর

এই সমাধান দুর্দান্ত কাজ করে। তবে, প্রক্রিয়াজাতকরণের সময় এটি কত ব্যয়বহুল? এটি ডাবল অবহেলা করে কাজ করে বলে মনে হচ্ছে।
আবেল কালেজো

30

প্রশ্নটি দীর্ঘদিন থেকেই ইতিমধ্যে সমাধান হয়েছে, তবে ভবিষ্যতের রেফারেন্সের জন্য একটি সম্ভাব্য সমাধান

b = a.slice(0);

সাবধানতা অবলম্বন করুন, এটি শুধুমাত্র তখনই সঠিকভাবে কাজ করে যদি কোনও সংখ্যা এবং স্ট্রিংয়ের একটি নেস-নেস্টেড অ্যারে হয়


28

newVariable = originalVariable.valueOf();

আপনি ব্যবহার করতে পারেন বস্তুর জন্য, b = Object.assign({},a);


4
অবজেক্টের জন্য আপনি ব্যবহার করতে পারেন, b = অবজেক্ট.স্যাসাইন ({}, ক);
কিশোর পাতিল

15

এটার কারন খুবিই সাধারন. জাভাস্ক্রিপ্ট রেফারেন্সগুলি ব্যবহার করে, সুতরাং যখন আপনি বরাদ্দ করেন তখন আপনাকে আপডেট করার সময় আপনাকে b = aএকটি রেফারেন্স বরাদ্দ করা bহয়ab

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

function clone(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] = clone(obj[i]);
        }
        return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
        var 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.");
}

ধন্যবাদ! আমি একটি নতুন প্রশ্ন পোস্ট করার আগে আমি সেই পোস্টটি দেখেছি। তবে এটি আমার দৃশ্যে সহায়তা করবে কিনা তা সম্পর্কে আমি অনিশ্চিত ছিলাম। আমার যা প্রয়োজন তা প্রমাণিত হয়।
রটউইক গাঙ্গুরদে

প্রথমটি if (obj instanceof x) { ... }বাদে সব কি আর হওয়া উচিত নয়?
জ্যাক

@ জ্যাক এই ক্ষেত্রে নয়। প্রতিটি ই-বডি (সুদের) একটি মান ফেরত দেয়। (পরবর্তী যদি আগে ফাংশনটি প্রস্থান করে)
বিটারব্লু

8

উত্তরগুলি এত জটিল কেন আমি বুঝতে পারি না। জাভাস্ক্রিপ্টে, আদিম (স্ট্রিং, সংখ্যা ইত্যাদি) মান দ্বারা পাস করা হয় এবং অনুলিপি করা হয়। অ্যারেগুলি সহ অবজেক্টগুলি রেফারেন্স দ্বারা পাস করা হয়। যাই হোক না কেন, 'এ' এর জন্য একটি নতুন মান বা অবজেক্ট রেফারেন্স বরাদ্দকরণ 'বি' পরিবর্তন করবে না। তবে 'ক' এর বিষয়বস্তু পরিবর্তন করলে 'খ' এর বিষয়বস্তু পরিবর্তন হবে।

var a = 'a'; var b = a; a = 'c'; // b === 'a'

var a = {a:'a'}; var b = a; a = {c:'c'}; // b === {a:'a'} and a = {c:'c'}

var a = {a:'a'}; var b = a; a.a = 'c'; // b.a === 'c' and a.a === 'c'

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


4

স্ট্রিং বা ইনপুট মানগুলির জন্য আপনি কেবল এটি ব্যবহার করতে পারেন:

var a = $('#some_hidden_var').val(),
b = a.substr(0);

আপনি কেন একটি আদিম পদক্ষেপ নেবেন? কেবল এটি বরাদ্দ করুন, এটি স্ট্রিংটি অনুলিপি করে। কেবলমাত্র বস্তু এবং অ্যারে (যা বস্তু) রেফারেন্স দ্বারা পাস হয়।
ট্রেনটন ডি অ্যাডামস

3

এখানে বেশিরভাগ উত্তরগুলি অন্তর্নির্মিত পদ্ধতিগুলি ব্যবহার করে বা লাইব্রেরি / ফ্রেমওয়ার্ক ব্যবহার করে। এই সহজ পদ্ধতিটি সূক্ষ্মভাবে কাজ করা উচিত:

function copy(x) {
    return JSON.parse( JSON.stringify(x) );
}

// Usage
var a = 'some';
var b = copy(a);
a += 'thing';

console.log(b); // "some"

var c = { x: 1 };
var d = copy(c);
c.x = 2;

console.log(d); // { x: 1 }

প্রতিভা! অন্যান্য পদ্ধতিগুলি তাদের মধ্যে অ্যারেগুলি সহ সমস্ত কিছু অভিধানে পরিণত করে। এটির সাহায্যে আমি অবজেক্টটির ক্লোন করেছি এবং সামগ্রীগুলি এর থেকে ভিন্ন নয়:Object.assign({},a)
টিকি

0

আপাতত আমি নিজেই এটি সমাধান করেছি। মূল মানটিতে 2 টি উপ-বৈশিষ্ট্য রয়েছে। আমি বৈশিষ্ট্যগুলি সহ একটি নতুন বস্তুর সংস্কার করেছি aএবং তারপরে এটি নির্ধারিত করেছি b। এখন আমার ইভেন্ট হ্যান্ডলারটি কেবল আপডেট হয় bএবং আমার আসলটি aযেমন হয় তেমন থাকে।

var a = { key1: 'value1', key2: 'value2' },
    b = a;

$('#revert').on('click', function(e){
    //FAIL!
    b = a;

    //WIN
    b = { key1: a.key1, key2: a.key2 };
});

এটি কাজ করে। উপরের ব্যতীত আমি আমার কোডের কোথাও একটি লাইনও পরিবর্তন করি নি এবং এটি কীভাবে আমি এটি চেয়েছিলাম ঠিক ঠিক তা কাজ করে। তাই, আমার বিশ্বাস, অন্য কিছুই আপডেট ছিল a


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