मैं ES6 + में एक साथ दो जावास्क्रिप्ट वस्तुओं को कैसे मिलाऊं?


141

मैं हमेशा इस तरह कोड लिखने से थक गया हूँ:

function shallowExtend(obj1,obj2){
  var key;
  for ( key in obj2 ) {
    if ( obj2.hasOwnProperty(key) === false )  continue;
    obj1[key] = obj2[key]
  }
}

या अगर मैं खुद कोड नहीं लिखना चाहता हूं, तो एक पुस्तकालय लागू करें जो पहले से ही ऐसा करता है। निश्चित रूप से ES6 + इस पर बचाव के लिए आ रहा है Object.prototype.extend(obj2...)या हमें ऐसा कुछ प्रदान करेगाObject.extend(obj1,obj2...)

तो क्या ES6 + इस तरह की कार्यक्षमता प्रदान करता है? यदि पहले से ही नहीं है, तो क्या ऐसी कार्यक्षमता की योजना है? अगर योजना नहीं बनाई है, तो क्यों नहीं?


3
तो आपने इसे अपने पुस्तकालय में क्यों नहीं जोड़ा है ?
RobG

12
@RobG यह सवाल इस उम्मीद के बारे में है कि ES6 हमें पहले से इस तरह के बॉयलरप्लेट बकवास की आवश्यकता होने से दूर कर देगा। इसके लिए इसके लायक क्या है: github.com/balupton/bal-util/blob/…
baltonton

मुझे नहीं लगता कि एक वस्तु से दूसरी वस्तु में नाम / मूल्य जोड़े की प्रतिलिपि बनाने का एक सामान्य तरीका है। क्या आप केवल स्वयं के गुणों या [[Prototype]]श्रृंखला पर उन लोगों के साथ व्यवहार करते हैं ? क्या आप "गहरी" या "उथली" प्रतियां करते हैं? गैर-एन्यूमरेबल और गैर-लेखन गुणों के बारे में क्या? मुझे लगता है कि मेरे पास एक छोटा सा पुस्तकालय समारोह होगा जो मुझे चाहिए, और ज्यादातर यह वैसे भी परिहार्य है।
रॉब

जवाबों:


206

आप Object.assign का उपयोग करके ES6 में उथले विलय / विस्तार / असाइन करने में सक्षम होंगे:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

वाक्य - विन्यास:

Object.assign ( लक्ष्य , स्रोत );

जहां ... स्रोत स्रोत का प्रतिनिधित्व करते हैं।

उदाहरण:

var obj1 = {name: 'Daisy', age: 30};
var obj2 = {name: 'Casey'};

Object.assign(obj1, obj2);

console.log(obj1.name === 'Casey' && obj1.age === 30);
// true

64
एक छोटा नोट: Object.assign लक्ष्य को बदल देता है। यदि वह नहीं है जो आप चाहते हैं तो आप इसे किसी खाली वस्तु के साथ कह सकते हैं:let merged = Object.assign({}, source1, source2);
david

20
कृपया ध्यान दें कि यह एक उथला विस्तार है ... नेस्टेड वस्तुओं को मर्ज नहीं किया जाता है
मोनोज़ोन

@monzonj, नेस्टेड या माउट का उपयोग किए बिना, नेस्टेड ऑब्जेक्ट्स को विस्तारित करने का कोई विकल्प नहीं है?
जोआओ फाल्को

1
एक पुस्तकालय का उपयोग किए बिना गहरी नेस्टेड वस्तुओं को मर्ज करने का एक अच्छा तरीका है Object.assign: मेरा जवाब यहां देखें
रुस्लान

नेस्टेड ऑब्जेक्ट्स का विस्तार करने के लिए एक पुराना तरीका हैJSON.parse(JSON.stringify(src))
आंद्रे फिगयेरिडो

162

आप इसके लिए ऑब्जेक्ट स्प्रेड सिंटैक्स का उपयोग कर सकते हैं :

const merged = {...obj1, ...obj2}

सरणियों के लिए प्रसार ऑपरेटर पहले से ही ES6 (ES2015) का हिस्सा था, लेकिन वस्तुओं के लिए इसे ES9 (ES2018) में भाषा युक्ति में जोड़ा गया था। इसका प्रस्ताव बबल जैसे उपकरण में डिफ़ॉल्ट रूप से बहुत पहले सक्षम हो चुका है।


3
आधिकारिक तौर पर अब इसे ES2015 नहीं कहा जाता है: P तब से जब विनाशकारी ES6 का हिस्सा नहीं है? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… रनिंग const ob1 = {foo: 123}; const ob2 = {bar: 234}; const merged = {...ob1, ...ob2}; console.log(merged){ foo: 123, bar: 234 }
बैबल

9
यह विनाशकारी नहीं है, यह फैल रहा है - और नहीं, वस्तुओं के लिए यह ईएस 6 का हिस्सा नहीं है। आपको अपने बाबेल में प्रयोगात्मक ईएस 7 ड्राफ्ट को अक्षम करना चाहिए।
बरगी

2
मुझे माफ़ कर दो। तुम सही हो। यह इस समय एक बैबल स्टेज 2 फीचर है। github.com/sebmarkbage/ecmascript-rest-spread मुझे कभी भी इस बात का एहसास नहीं हुआ कि मैं इसे शुरुआत से ही इस्तेमाल कर रहा हूं और यह डिफ़ॉल्ट रूप से सक्षम है। लेकिन जब से तुम वैसे भी transpile की जरूरत है, और फैली हुई वस्तु एक बहुत ही सीधी बात है मैं इसे वैसे भी सुझाऊंगा। मुझे यह पसंद है।
थिएज कोएर्सलमैन 22

वे डिफ़ॉल्ट रूप से सक्षम हैं, वास्तव में? यह एक बग की तरह लगता है।
बरगी

2
"प्रस्ताव जो कि चरण 2 या उससे ऊपर हैं, डिफ़ॉल्ट रूप से सक्षम हैं"। babeljs.io/docs/usage/experimental
Thijs Koerselman

14

मुझे पता है कि यह एक पुराना मुद्दा है लेकिन ES2015 / ES6 में सबसे आसान समाधान वास्तव में काफी सरल है, Object.assign () का उपयोग करके

उम्मीद है कि यह मदद करता है, यह DEEP विलय भी करता है:

/**
 * Simple is object check.
 * @param item
 * @returns {boolean}
 */
export function isObject(item) {
  return (item && typeof item === 'object' && !Array.isArray(item) && item !== null);
}

/**
 * Deep merge two objects.
 * @param target
 * @param source
 */
export function mergeDeep(target, source) {
  if (isObject(target) && isObject(source)) {
    for (const key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, { [key]: {} });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, { [key]: source[key] });
      }
    }
  }
  return target;
}

उदाहरण उपयोग:

mergeDeep(this, { a: { b: { c: 123 } } });
// or
const merged = mergeDeep({a: 1}, { b : { c: { d: { e: 12345}}}});  
console.dir(merged); // { a: 1, b: { c: { d: [Object] } } }

7

के अलावा Object.mixinवर्तमान में चर्चा हो रही है व्यवहार आप के लिए पूछ रहे हैं का ख्याल रखना। https://mail.mozilla.org/pipermail/es-discuss/2012-December/027037.html

हालाँकि यह अभी ईएस 6 ड्राफ्ट में नहीं है, ऐसा लगता है कि इसके लिए बहुत अधिक समर्थन है, इसलिए मुझे लगता है कि यह जल्द ही ड्राफ्ट में दिखाई देगा।


13
.mixinTC39 द्वारा गिरा दिया गया है।
नं।

5
चेतावनी - यह उत्तर अब सही नहीं है, जैक द्वारा उत्तर को एक सही और काम करने के दृष्टिकोण के लिए देखें।
बेंजामिन Gruenbaum

Object.mixin को Object.assign द्वारा बदल दिया गया है
gotofritz

7

ES6

Object.assign(o1,o2) ; 
Object.assign({},o1,o2) ; //safe inheritance
var copy=Object.assign({},o1); // clone o1
//------Transform array of objects to one object---
var subjects_assess=[{maths:92},{phy:75},{sport:99}];
Object.assign(...subjects_assess); // {maths:92,phy:75,sport:99}

ईएस 7 या बैबेल

{...o1,...o2} // inheritance
 var copy= {...o1};

1
@FilipBartuzi ईएस 6 नहीं है जिसे आपने लिंक किया है। लेकिन यह मूल रूप से लॉश / अंडरस्कोर में _.extend () के बराबर कर रहा है।
Nostalg.io

5

शायद ES5 Object.definePropertiesविधि काम करेगा?

जैसे

var a = {name:'fred'};
var b = {age: {value: 37, writeable: true}};

Object.defineProperties(a, b);

alert(a.age); // 37

MDN प्रलेखन: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperties


हालांकि सावधान रहें। पर कम से कम एक ब्राउज़र इस प्रदर्शन प्रभाव पड़ता है।
रूबेन मोरिस

1
मुझे लगता है कि सबसे दिलचस्प हिस्सा definePropertiesखुद के गुणों को परिभाषित करता है। यह [[prototype]]श्रृंखला पर गुणों को अधिलेखित नहीं करता है , यह उन्हें छाया देता है।
रॉब

2
अच्छा सुझाव, हालांकि वास्तव में एक विस्तार नहीं है क्योंकि यह परिभाषित करने के लिए अधिक है कि गुणों का व्यवहार कैसे किया जाना चाहिए ... एक सीधी वस्तु ।defineProperties (obj1, obj2) करने से अप्रत्याशित परिणाम होंगे।
बालुपटन डेस

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