किसी अन्य ऑब्जेक्ट में ऑब्जेक्ट गुणों की नकल कैसे करें?


185

वस्तु को देखते हुए:

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

कैसे मैं किसी अन्य वस्तु के अंदर गुण कॉपी कर सकते हैं ( secondObject) इस तरह:

var secondObject = {
    key1 : 'value1',
    key2 : 'value2',
    key3 : 'value3',
    key4 : 'value4'
};

के लिए एक संदर्भ का उपयोग कर firstObject? कुछ इस तरह:

var secondObject = {
    firstObject,
    key3 : 'value3',
    key4 : 'value4'
};

(यह काम नहीं करता है ... मैंने इसे केवल बड़ी लाइनों में दिखाने के लिए रखा है कि मैं कोड को कैसे संरचना करना चाहूंगा)।

किसी भी जावास्क्रिप्ट चौखटे का उपयोग किए बिना एक समाधान संभव है ?


3
यहाँ उत्तर दिया गया: stackoverflow.com/questions/171251/…
केल्विन

1
सवाल यह है कि क्या आप उथली या गहरी नकल चाहते हैं? अगर गहरी, कितनी गहरी?
जॉर्ज

5
एफडब्ल्यूआईडब्ल्यू, उन्हें "गुण" कहा जाता है, "विशेषता नहीं।"
टीजे क्राउडर

यहाँ वास्तव में कुछ बदसूरत है जो फिर भी काम करता है (वास्तव में अनुशंसित नहीं है! बस एक लाइनर प्रूफ-ऑफ-कांसेप्ट):secondObject = JSON.parse('{' + JSON.stringify(firstObject).match(/^.(.*).$/)[1] + ',' + JSON.stringify(secondObject).match(/^.(.*).$/)[1] + '}');
बेन ली

@TJCrowder: मैंने प्रश्न सही किया ... धन्यवाद।
इगोर पोपोव

जवाबों:


213
for(var k in firstObject) secondObject[k]=firstObject[k];

3
@BenLee, जो आप यहां याद कर रहे हैं, वह यह है कि इगोर ने इसके लिए उसका सटीक उपयोग दिखाया है, जिसमें hasOwnPropertyवह बेकार है। मैं अपने सूचक उपयोगी पाते हैं, वहीं मैं लागू करने के विचार पर विचार किसी भी करने के लिए नियमों को किसी भी हानिकारक और मूर्ख स्थिति। इन सभी चालित विकास प्रथाओं की तरह जो चल रही हैं, इसलिए इसे व्यक्तिगत न लें ...
माइकल क्रेलिन - हैकर

1
@ माइकलक्रेलिन-हैकर, जो आप यहां याद कर रहे हैं वह यह है कि स्टैकऑवरफ्लो केवल ओपी के लाभ के लिए नहीं है। यह भविष्य के आगंतुकों के लिए एक संदर्भ के रूप में उपयोग किया जाता है जिनके पास थोड़ा अलग उपयोग के मामले हो सकते हैं, जहां सूचक उपयोगी हो सकता है।
बेन ली

@BenLee, मैं IgPopov ;-) नहीं हूं और ओपी नहीं होने के नाते, मैंने पहले ही कहा था कि मुझे पॉइंटर उपयोगी लगता है और आपका जवाब भी, यह "आप वास्तव में" का उपयोग करना चाहिए जो मुझे नापसंद है।
माइकल क्रेलिन -

23
आप एक hasOwnProperty()परीक्षा छोड़ देते हैं और चीजें काम करती रहती हैं। जब तक वे बंद नहीं हो जाते, क्योंकि समय के साथ आपकी वस्तुएं अधिक जटिल हो गईं। सिवाय इसके कि यह कोड के एक असंबंधित हिस्से में रहस्यमय तरीके से टूट जाता है क्योंकि बहुत अधिक नकल की गई थी। और आपके पास डीबगिंग के लिए कोई संदर्भ नहीं है। जेएस इस तरह बेकार है, इसलिए ऐसी समस्याओं को रोकने के लिए सावधानीपूर्वक कोडिंग विवेकपूर्ण है।
एली बेंडरस्की

2
मुझे लगता है कि इस उत्तर को निम्नलिखित लिंक डेवलपर. mozilla.org/en-US/docs/Web/JavaScript/Reference/… const target = {a: 1, b: 2} के अनुसार अपडेट किया जाना चाहिए ; const स्रोत = {b: 4, c: 5}; const returnTarget = Object.assign (लक्ष्य, स्रोत); console.log (लक्ष्य); // अपेक्षित आउटपुट: ऑब्जेक्ट {a: 1, b: 4, c: 5} कंसोल.लॉग (रिटर्नटार्गेट); // अपेक्षित आउटपुट: ऑब्जेक्ट {a: 1, b: 4, c: 5}
Elbassel

170

यहाँ @ Bardzuśny के उत्तर से एक संकेत लेते हुए, ES6 ने एक देशी समाधान दिया है: Object.assign()फ़ंक्शन!

उपयोग सरल है:

Object.assign(secondObject, firstObject);

बस!

अभी समर्थन स्पष्ट रूप से खराब है; केवल फ़ायरफ़ॉक्स (34+) इसे आउट-ऑफ-द-बॉक्स का समर्थन करता है, जबकि क्रोम (45+) और ओपेरा (32+) को सेट करने के लिए 'प्रयोगात्मक ध्वज' की आवश्यकता होती है।

समर्थन में सुधार हो रहा है, क्रोम, फ़ायरफ़ॉक्स, ओपेरा, सफारी और एज के नवीनतम संस्करणों के साथ इसका समर्थन (IE उल्लेखनीय रूप से कोई समर्थन नहीं है।) ट्रांसप्लर्स बबेल और ट्रेसुर की तरह ही उपलब्ध हैं। अधिक जानकारी के लिए यहां देखें


4
+1, एक और अच्छा ES6 फीचर। बेशक ब्राउज़र / यहां तक ​​कि Node.JS समर्थन में अभी कमी है, लेकिन जैसा कि आपने उल्लेख किया है, ट्रांसपैरर्स उपलब्ध हैं। और अगर आप उन्हें पसंद नहीं करते हैं - shims: github.com/paulmillr/es6-shim (या स्टैंडअलोन, Object.assign()-नहीं शिम: github.com/ljharb/object.assign )।
बार्डज़ुस्नी

1
@ Xoyce यदि आप लिंक किए गए MDN पृष्ठ की जाँच करते हैं, तो यह स्पष्ट रूप से बताता है कि "यदि स्रोत मान किसी ऑब्जेक्ट का संदर्भ है, तो यह केवल उस संदर्भ मान की प्रतिलिपि बनाता है।" तो यह वास्तव में संदर्भ को संरक्षित करता है, और ऑब्जेक्ट को कॉपी नहीं करता है। अप्रत्याशित व्यवहार के खिलाफ आपकी चेतावनी अभी भी उपयुक्त है, और यह उचित अपेक्षाओं पर खरी उतरती है।
DIMM रीपर

@ASTafiz मैंने आपका संपादन वापस कर दिया, क्योंकि इस पृष्ठ पर प्रश्न और अन्य उत्तर "फ़र्स्टऑबजेक्ट" और "सेकंडऑब्जेक्ट" नामों का उपयोग करते हैं, इसलिए मैंने स्पष्टता और स्थिरता के लिए यहां उन्हीं नामों का उपयोग किया।
DIMM रीपर

यदि यह प्रश्न के अनुरूप है तो ठीक है।
मुस्तफ़िज़ रहमान

1
@ पीडीएम येप - देखें किंगपॉपी का जवाब
DIMM रीपर

101

प्रति ES6 - स्प्रेड सिंटैक्स :

आप बस का उपयोग कर सकते हैं:

const thirdObject = {
   ...firstObject,
   ...secondObject   
}

यह इन वस्तुओं को संदर्भ द्वारा पारित करने की समस्याओं से बचा जाता है।

इसके अतिरिक्त यह उन वस्तुओं का ध्यान रखता है जिनके पास गहरे घोंसले हैं।


2
वाह, यह वास्तव में बहुत बढ़िया है :) उत्तर के लिए धन्यवाद। जाहिर है, मुझे इसकी कोई आवश्यकता नहीं है (क्योंकि यह कुछ समय पहले था), लेकिन यह किसी और की मदद कर सकता है।
इगोर पोपोव

1
ES6 के एक और अधिक कूलर उपयोग के लिए +1! एमडीएन डॉक्स ऊपर उल्लिखित है, वस्तुओं पर प्रसार ऑपरेटर का उपयोग करने का उल्लेख नहीं करता है, इसलिए मैंने इसे कार्रवाई में देखने के लिए एक बेला बनाया: es6fiddle.net/im3ifsg0
DIMM रीपर

1
@jaepage - संदर्भ के लिए अच्छी टिप्पणी। एक वस्तु (मूल प्रश्न के अनुसार) सरल संपत्ति नामों के साथ है iterable।
KingPuppy

1
क्रोम में काम करता है, यह ईएस 6 है, आपको वर्तमान में बैबेल या कुछ ईएस 6 ट्रांसपिलर की आवश्यकता होगी। भविष्य में सभी ब्राउज़र को इस सिंटैक्स का समर्थन करने की उम्मीद है।
किंगपूपी

89

पहले ऑब्जेक्ट के गुणों के माध्यम से लूप करें और उन्हें दूसरी ऑब्जेक्ट पर असाइन करें, जैसे:

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

var secondObject = {
    key3 : 'value3',
    key4 : 'value4'
};

for (var prop in firstObject) {
    if (firstObject.hasOwnProperty(prop)) {
        secondObject[prop] = firstObject[prop];
    }
}

for- inपाश पर्याप्त नहीं है, आप की जरूरत hasOwnProperty। विस्तृत विवरण के लिए http://bonsaiden.github.com/JavaScript-Garden/#object.forinloop देखें ।


@ रोब, मुझे नहीं लगा कि ओपी referenceतकनीकी अर्थों में उपयोग कर रहा है। मुझे लगता है कि वह सिर्फ प्राकृतिक-भाषा का अर्थ है "संदर्भित"।
बेन ली

1
@ रोब: ओपी ने वास्तव में कहा था "कॉपी।"
टीजे क्राउडर

49

यहां नेक्रोमैंसर बजाना, क्योंकि ES5 हमें लाया Object.keys(), इन सभी .hasOwnProperty()जांचों से हमें बचाने की क्षमता के साथ ।

Object.keys(firstObject).forEach(function(key) {
  secondObject[key] = firstObject[key];
});

या, इसे एक फंक्शन में लपेटना (लिकैश की सीमित "कॉपी" _.assign()):

function assign(object, source) {
  Object.keys(source).forEach(function(key) {
    object[key] = source[key];
  });
}

assign(secondObject, firstObject); // assign firstObject properties to secondObject

Object.keys()अपेक्षाकृत नई विधि है, सबसे विशेष रूप से: IE में उपलब्ध नहीं है। 9. वही वास्तव में .forEach()सरणी विधि के लिए जाता है , जिसे मैंने नियमित forलूप के स्थान पर उपयोग किया था ।

सौभाग्य से, इन प्राचीन ब्राउज़रों के लिए es5-shim उपलब्ध है, जो कई ES5 सुविधाओं (उन दो सहित) को पॉलीफ़िल करेगा।

(मैं शांत, नई भाषा सुविधाओं के उपयोग से वापस रखने के विरोध में पॉलीफ़िल के लिए सभी हूँ।)


कहीं से भी 2 डाउनवोट निकले। छोटे मौके पर यह कहते हुए कि वे लोग इस टिप्पणी को पढ़ेंगे - उनके लिए वास्तविक कारण क्या है? कुछ भी आप मेरे उत्तर में परिवर्तन / सुधार करने का सुझाव देंगे?
बर्डज़ुसनी

1
यह निश्चित रूप से शीर्ष पर उठने का हकदार है, साथ ही साथ ऑब्जेक्ट ने इनिशियलाइज़र को और नीचे (ES6) में फैलाया - यह तीर के कार्यों के साथ भी साफ दिखता है!
mjohnsonengr

12

Necro'ing ताकि लोग hasOwnProperty और वास्तविक वस्तु जांच के साथ एक गहरी प्रतिलिपि विधि पा सकें:

var extend = function (original, context, key) {
  for (key in context)
    if (context.hasOwnProperty(key))
      if (Object.prototype.toString.call(context[key]) === '[object Object]')
        original[key] = extend(original[key] || {}, context[key]);
      else
        original[key] = context[key];
  return original;
};

ध्यान दें कि यह डीप-कॉपी एरेज़ या फ़ंक्शन ऑब्जेक्ट नहीं करता है (लेकिन यह अन्य सभी प्रकार की ऑब्जेक्ट्स को डीप-कॉपी करता है)।
मैट ब्राउन ने

1
हाँ, यदि आप डीप एरे को कॉपी करना चाहते हैं तो आप इसमें शामिल होने के लिए टाइप चेक को संशोधित करें'[object Array]'
निजकोकुन

12

ऑब्जेक्ट को संयोजित करने के लिए एक Object.assign का उपयोग कर सकता है । यह आम संपत्ति को दाएं से बाएं की ओर मिलाएगा और ओवरराइड करेगा यानी बाएं में समान संपत्ति को दाएं से ओवरराइड किया जाएगा।

और स्रोत वस्तुओं को म्यूट करने से बचने के लिए पहले में एक खाली वस्तु की आपूर्ति करना महत्वपूर्ण है। स्रोत ऑब्जेक्ट्स को साफ छोड़ दिया जाना चाहिए क्योंकि Object.assign()स्वयं एक नई वस्तु देता है।

उम्मीद है की यह मदद करेगा!

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

var secondObject = {
    key3 : 'value3',
    key4 : 'value4'
};

var finalObject = Object.assign({}, firstObject, secondObject)

console.log(finalObject)


लेकिन क्या होगा अगर आप इसे पहली वस्तु को बदलना चाहते हैं ? आपके पास ऑब्जेक्ट A और ऑब्जेक्ट B है, और आप चाहते हैं कि वह ऑब्जेक्ट A को म्यूट करे ताकि सभी गुण ऑब्जेक्ट B पर समान हों? क्या आप Object.assign (A, B) करेंगे?
TKoL

उस मोज़िला डेवलपर नेटवर्क पेज के अनुसार आईई, एंड्रॉइड वेबव्यू, एंड्रॉइड ओपेरा पर दुख की बात नहीं है।
यति९

6

KingPuppy विचार और ओपी विचार (उथले प्रतिलिपि) में सुधार - मैं केवल ओपी में 3 डॉट्स जोड़ता हूं "उदाहरण" :)

var secondObject = {
    ...firstObject,
    key3 : 'value3',
    key4 : 'value4'
};


4

यह काम करना चाहिए, यहाँ परीक्षण किया गया

var secondObject = {
    firstObject: JSON.parse(JSON.stringify(firstObject)),
    key3 : 'value3',
    key4 : 'value4'
};

नोट : यह firstObject
नोट 2 के तरीकों की नकल नहीं करेगा : पुराने ब्राउज़रों में उपयोग के लिए, आपको एक json parser की आवश्यकता होगी
नोट 3 : संदर्भ द्वारा असाइन करना एक व्यवहार्य विकल्प है, खासकर यदि firstObjectविधियाँ शामिल हैं। दिए गए jsfiddle उदाहरण के अनुसार समायोजित


3

दुर्भाग्य से, आप उस तरह एक वस्तु में एक चर के लिए एक संदर्भ नहीं डाल सकते हैं। हालाँकि, आप एक फ़ंक्शन बना सकते हैं जो ऑब्जेक्ट के मूल्यों को किसी अन्य ऑब्जेक्ट में कॉपी करता है।

function extend( obj1, obj2 ) {
    for ( var i in obj2 ) {
        obj1[i] = obj2[i];
    }
    return obj1;
}

var firstObject = {
    key1: "value1",
    key2: "value2"
};

var secondObject = extend({
    key3: "value3",
    key4: "value4"
}, firstObject );

यह भी देशी गुणों की नकल करेगा। और उन गुणों के बारे में कैसे जो स्वयं वस्तुएं हैं?
KooiInc

1

यदि आप केवल दूसरी संपत्तियों में मौजूद गुणों को हथियाना चाहते हैं, तो आप Object.keysपहली वस्तु के गुणों को हथियाने के लिए उपयोग कर सकते हैं , आप दो गुण कर सकते हैं:

ए) map साइड इफेक्ट्स का उपयोग करके पहली वस्तु के गुणों को दूसरी वस्तु को सौंपने के लिए:

var a = {a:100, b:9000, c:300};
var b = {b:-1};

Object.keys(a).map(function(key, index) {
    if (typeof b[key] !== 'undefined') {
        console.log(key);
        b[key] = a[key];    
    }
});

बी) या reduceएक नई वस्तु बनाने के लिए और दूसरी वस्तु को सौंपने के लिए। विदित हो कि यह विधि अन्य गुणों को प्रतिस्थापित करती है , दूसरी वस्तु इससे पहले हो सकती है जो पहली वस्तु से मेल नहीं खाती:

var a = {a:100, b:9000, c:300};
var b = {b:-1, d:-1}; // d will be gone

b = Object.keys(a).reduce(function(result, current) {
    if (typeof b[current] !== 'undefined') {
        result[current] = a[current];   
    }
    return result;
}, {});

1

संपत्ति प्रसार संकेतन का उपयोग करें। इसे ES2018 में जोड़ा गया था (सरणियों / पुनरावृत्तियों के लिए फैला हुआ था, पहले ES2015 था), {... firstObject} सभी असाध्य गुणों को असतत गुणों के रूप में फैलाता है।

let secondObject = {
      ...firstObject,
      key3 : 'value3',
      key4 : 'value4'
    }

क्या आप कृपया अपने उत्तर पर कुछ संदर्भ दे सकते हैं और यह सवाल क्यों हल कर रहे हैं
तामीर क्लेन

0

मैं दूसरे ऑबजेक्ट के प्रोटोटाइप के रूप में FirstObject का उपयोग करूंगा, और प्रॉपर्टी डिस्क्रिप्टर जोड़ें:

var secondObject = Object.create(firstObject, {
      key3: {value: "value3", writable: true, configurable: true, enumerable: true},
      key4: {value: "value4", writable: true, configurable: true, enumerable: true}
      });

यह निश्चित रूप से वन-लाइनर नहीं है, लेकिन यह आपको अधिक नियंत्रण देता है। यदि आप संपत्ति के विवरणकों में रुचि रखते हैं, तो मैं इस लेख को पढ़ने का सुझाव देता हूं: http://patrickdelancy.com/2012/09/property-descriptors-in-javascript/#comment-2062 और MDN पृष्ठ https: //developm.mozilla। org / en-US / docs / वेब / जावास्क्रिप्ट / संदर्भ / Global_Objects / वस्तु / बनाने

आप केवल मान निर्दिष्ट कर सकते हैं और विवरणकर्ताओं को छोड़ सकते हैं और इसे थोड़ा छोटा कर सकते हैं:

var secondObject = Object.create(firstObject, {
      key3: {value: "value3"}
      key4: {value: "value4"}
  });

संगतता: ECMAScript 5, इसलिए IE9 +


0
var firstObject = {
     key1: "value1",
     key2: "value2"
};

var secondObject = {
     key3: "value3",
     key4: "value4"
     copy: function(firstObject){
           this.key1 = firstObject.key1;
           this.key2 = firstObject.key2;
     }
 };

Follwing विधि का उपयोग गुणों की नकल करेगा

secondObject.copy(firstObject)

मैं जावास्क्रिप्ट के लिए बहुत नया हूँ, लेकिन यह काम कर पाया। थोड़ा बहुत लंबा मुझे लगता है, लेकिन यह काम करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.