javascript उनल मैं गतिशील रूप से दो जावास्क्रिप्ट वस्तुओं के गुणों को कैसे विलय कर सकता हूं?




जावास्क्रिप्ट डाउनलोड (20)

कोड की एक पंक्ति में एन वस्तुओं के गुणों को मर्ज करें

एक Object.assign विधि Object.assign 2015 (ईएस 6) मानक का हिस्सा है और आपको वही करता है जो आपको चाहिए। ( IE समर्थित नहीं है)

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

ऑब्जेक्ट.साइन () विधि का प्रयोग एक या अधिक स्रोत ऑब्जेक्ट्स से लक्ष्य ऑब्जेक्ट पर सभी समृद्ध गुणों के मानों की प्रतिलिपि बनाने के लिए किया जाता है।

और पढो...

पुराने ब्राउज़रों का समर्थन करने के लिए पॉलीफिल :

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

https://code.i-harness.com

मुझे रनटाइम पर दो (बहुत ही सरल) जावास्क्रिप्ट ऑब्जेक्ट्स को मर्ज करने में सक्षम होना चाहिए। उदाहरण के लिए मैं यह करना चाहता हूं:

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog' }

obj1.merge(obj2);

//obj1 now has three properties: food, car, and animal

क्या किसी के पास इस के लिए एक स्क्रिप्ट है या ऐसा करने के लिए एक तरीके से पता है? मुझे रिकर्सन की आवश्यकता नहीं है, और मुझे फ़ंक्शंस मर्ज करने की आवश्यकता नहीं है, केवल फ्लैट ऑब्जेक्ट्स पर विधियां।


JQuery के समान (), आपके पास AngularJS में एक ही कार्य है:

// Merge the 'options' object into the 'settings' object
var settings = {validate: false, limit: 5, name: "foo"};
var options  = {validate: true, name: "bar"};
angular.extend(settings, options);

आप वस्तु फैल गुणों का उपयोग कर सकते हैं - वर्तमान में एक चरण 3 ईसीएमएस्क्रिप्ट प्रस्ताव।

const obj1 = { food: 'pizza', car: 'ford' };
const obj2 = { animal: 'dog' };

const obj3 = { ...obj1, ...obj2 };
console.log(obj3);


आप बस jQuery extend उपयोग कर सकते extend

var obj1 = { val1: false, limit: 5, name: "foo" };
var obj2 = { val2: true, name: "bar" };

jQuery.extend(obj1, obj2);

अब obj1 में obj1 और obj2 सभी मान शामिल हैं


दिए गए समाधानों को source.hasOwnProperty(property) करने से पहले source.hasOwnProperty(property) loops में source.hasOwnProperty(property) को जांचने के लिए संशोधित किया जाना चाहिए - अन्यथा, आप पूरी प्रोटोटाइप श्रृंखला के गुणों की प्रतिलिपि बनाते हैं, जो शायद ही कभी वांछित है ...


ध्यान दें कि underscore.js का underscorejs.org/#extend एक-लाइनर में करता है:

_.extend({name : 'moe'}, {age : 50});
=> {name : 'moe', age : 50}

बस अगर कोई Google क्लोजर लाइब्रेरी का उपयोग कर रहा है:

goog.require('goog.object');
var a = {'a': 1, 'b': 2};
var b = {'b': 3, 'c': 4};
goog.object.extend(a, b);
// Now object a == {'a': 1, 'b': 3, 'c': 4};

सरणी के लिए समान सहायक फ़ंक्शन मौजूद है :

var a = [1, 2];
var b = [3, 4];
goog.array.extend(a, b); // Extends array 'a'
goog.array.concat(a, b); // Returns concatenation of array 'a' and 'b'

बस वैसे, आप जो कुछ कर रहे हैं वह ओवरराइटिंग गुण है, विलय नहीं कर रहा है ...

इस प्रकार जावास्क्रिप्ट ऑब्जेक्ट एरिया वास्तव में विलय हो गया है: ऑब्जेक्ट्स में केवल कुंजियां जो ऑब्जेक्ट्स नहीं हैं, वे स्वयं से ओवरराइट की जाएंगी। बाकी सब कुछ वास्तव में विलय हो जाएगा। निस्संदेह आप इस व्यवहार को किसी भी चीज को ओवरराइट नहीं कर सकते हैं, जैसे कि to[n] is undefined , आदि ...:

var realMerge = function (to, from) {

    for (n in from) {

        if (typeof to[n] != 'object') {
            to[n] = from[n];
        } else if (typeof from[n] == 'object') {
            to[n] = realMerge(to[n], from[n]);
        }
    }
    return to;
};

उपयोग:

var merged = realMerge(obj1, obj2);

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

var merge = function() {
    var obj = {},
        i = 0,
        il = arguments.length,
        key;
    for (; i < il; i++) {
        for (key in arguments[i]) {
            if (arguments[i].hasOwnProperty(key)) {
                obj[key] = arguments[i][key];
            }
        }
    }
    return obj;
};

कुछ उदाहरण उपयोग करते हैं:

var t1 = {
    key1: 1,
    key2: "test",
    key3: [5, 2, 76, 21]
};
var t2 = {
    key1: {
        ik1: "hello",
        ik2: "world",
        ik3: 3
    }
};
var t3 = {
    key2: 3,
    key3: {
        t1: 1,
        t2: 2,
        t3: {
            a1: 1,
            a2: 3,
            a4: [21, 3, 42, "asd"]
        }
    }
};

console.log(merge(t1, t2));
console.log(merge(t1, t3));
console.log(merge(t2, t3));
console.log(merge(t1, t2, t3));
console.log(merge({}, t1, { key1: 1 }));

मैं ऑब्जेक्ट गुणों को मर्ज करने के लिए कोड के लिए googled और यहां समाप्त हो गया। हालांकि, रिकर्सिव विलय के लिए कोई कोड नहीं था इसलिए मैंने इसे स्वयं लिखा था। (हो सकता है कि jQuery का विस्तार रिकर्सिव बीटीडब्ल्यू है?) किसी भी तरह, उम्मीद है कि किसी और को भी यह उपयोगी लगेगा।

(अब कोड Object.prototype उपयोग नहीं करता है :)

कोड

/*
* Recursively merge properties of two objects 
*/
function MergeRecursive(obj1, obj2) {

  for (var p in obj2) {
    try {
      // Property in destination object set; update its value.
      if ( obj2[p].constructor==Object ) {
        obj1[p] = MergeRecursive(obj1[p], obj2[p]);

      } else {
        obj1[p] = obj2[p];

      }

    } catch(e) {
      // Property in destination object not set; create it and set its value.
      obj1[p] = obj2[p];

    }
  }

  return obj1;
}

एक उदाहरण

o1 = {  a : 1,
        b : 2,
        c : {
          ca : 1,
          cb : 2,
          cc : {
            cca : 100,
            ccb : 200 } } };

o2 = {  a : 10,
        c : {
          ca : 10,
          cb : 20, 
          cc : {
            cca : 101,
            ccb : 202 } } };

o3 = MergeRecursive(o1, o2);

वस्तु ओ 3 की तरह उत्पादन करता है

o3 = {  a : 10,
        b : 2,
        c : {
          ca : 10,
          cb : 20,
          cc : { 
            cca : 101,
            ccb : 202 } } };

यहाँ मेरा स्टैब है

  1. गहरी विलय का समर्थन करता है
  2. तर्कों को म्यूट नहीं करता है
  3. किसी भी तर्क लेता है
  4. ऑब्जेक्ट प्रोटोटाइप का विस्तार नहीं करता है
  5. किसी अन्य लाइब्रेरी पर निर्भर नहीं है ( jQuery , MooTools , Underscore.js , आदि)
  6. HasOwnProperty के लिए चेक शामिल है
  7. छोटा है :)

    /*
        Recursively merge properties and return new object
        obj1 &lt;- obj2 [ &lt;- ... ]
    */
    function merge () {
        var dst = {}
            ,src
            ,p
            ,args = [].splice.call(arguments, 0)
        ;
    
        while (args.length > 0) {
            src = args.splice(0, 1)[0];
            if (toString.call(src) == '[object Object]') {
                for (p in src) {
                    if (src.hasOwnProperty(p)) {
                        if (toString.call(src[p]) == '[object Object]') {
                            dst[p] = merge(dst[p] || {}, src[p]);
                        } else {
                            dst[p] = src[p];
                        }
                    }
                }
            }
        }
    
       return dst;
    }
    

उदाहरण:

a = {
    "p1": "p1a",
    "p2": [
        "a",
        "b",
        "c"
    ],
    "p3": true,
    "p5": null,
    "p6": {
        "p61": "p61a",
        "p62": "p62a",
        "p63": [
            "aa",
            "bb",
            "cc"
        ],
        "p64": {
            "p641": "p641a"
        }
    }
};

b = {
    "p1": "p1b",
    "p2": [
        "d",
        "e",
        "f"
    ],
    "p3": false,
    "p4": true,
    "p6": {
        "p61": "p61b",
        "p64": {
            "p642": "p642b"
        }
    }
};

c = {
    "p1": "p1c",
    "p3": null,
    "p6": {
        "p62": "p62c",
        "p64": {
            "p643": "p641c"
        }
    }
};

d = merge(a, b, c);


/*
    d = {
        "p1": "p1c",
        "p2": [
            "d",
            "e",
            "f"
        ],
        "p3": null,
        "p5": null,
        "p6": {
            "p61": "p61b",
            "p62": "p62c",
            "p63": [
                "aa",
                "bb",
                "cc"
            ],
            "p64": {
                "p641": "p641a",
                "p642": "p642b",
                "p643": "p641c"
            }
        },
        "p4": true
    };
*/


हार्मनी developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 2015 ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… निर्दिष्ट developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… जो यह करेगा।

Object.assign(obj1, obj2);

वर्तमान ब्राउज़र समर्थन बेहतर हो रहा है , लेकिन यदि आप ऐसे ब्राउज़र के लिए विकास कर रहे हैं जिनके पास समर्थन नहीं है, तो आप polyfill उपयोग कर सकते हैं।


deepmerge पर deepmerge की एक लाइब्रेरी GitHub : ऐसा लगता है कि कुछ कर्षण हो रहा है। यह एक स्टैंडअलोन है, जो npm और बॉवर पैकेज मैनेजर दोनों के माध्यम से उपलब्ध है।

मैं उत्तर से प्रतिलिपि कोड के बजाय इस पर उपयोग या सुधार करने के इच्छुक हूं।


ईसीएमएस्क्रिप्ट 2015 (ईएस 6) मानक विधि

/* For the case in question, you would do: */
Object.assign(obj1, obj2);

/** There's no limit to the number of objects you can merge.
 *  All objects get merged into the first object. 
 *  Only the object in the first argument is mutated and returned.
 *  Later properties overwrite earlier properties with the same name. */
const allRules = Object.assign({}, obj1, obj2, obj3, etc);

( एमडीएन जावास्क्रिप्ट संदर्भ देखें)

ES5 और इससे पहले के लिए विधि

for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }

ध्यान दें कि यह obj2 सभी गुणों को obj1 जोड़ देगा जो शायद आप नहीं चाहते हैं अगर आप अभी भी unmodified obj1 का उपयोग करना चाहते हैं।

यदि आप अपने प्रोटोटाइप पर एक फ्रेमवर्क का उपयोग कर रहे हैं तो आपको hasOwnProperty जैसी चेक के साथ hasOwnProperty , लेकिन वह कोड 99% मामलों के लिए काम करेगा।

उदाहरण समारोह:

/**
 * Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
 * @param obj1
 * @param obj2
 * @returns obj3 a new object based on obj1 and obj2
 */
function merge_options(obj1,obj2){
    var obj3 = {};
    for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
    for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
    return obj3;
}

Based on Markus' and vsync' answer , this is an expanded version. The function takes any number of arguments. It can be used to set properties on DOM nodes and makes deep copies of values. However, the first argument is given by reference.

To detect a DOM node, the isDOMNode() function is used (see question JavaScript isDOM — How do you check if a JavaScript Object is a DOM Object? )

It was tested in Opera 11, Firefox 6, Internet Explorer 8 and Google Chrome 16.

कोड

function mergeRecursive() {

  // _mergeRecursive does the actual job with two arguments.
  var _mergeRecursive = function (dst, src) {
    if (isDOMNode(src) || typeof src !== 'object' || src === null) {
      return dst;
    }

    for (var p in src) {
      if (!src.hasOwnProperty(p))
        continue;
      if (src[p] === undefined)
        continue;
      if ( typeof src[p] !== 'object' || src[p] === null) {
        dst[p] = src[p];
      } else if (typeof dst[p]!=='object' || dst[p] === null) {
        dst[p] = _mergeRecursive(src[p].constructor===Array ? [] : {}, src[p]);
      } else {
        _mergeRecursive(dst[p], src[p]);
      }
    }
    return dst;
  }

  // Loop through arguments and merge them into the first argument.
  var out = arguments[0];
  if (typeof out !== 'object' || out === null)
    return out;
  for (var i = 1, il = arguments.length; i < il; i++) {
    _mergeRecursive(out, arguments[i]);
  }
  return out;
}

कुछ उदाहरण

Set innerHTML and style of a HTML Element

mergeRecursive(
  document.getElementById('mydiv'),
  {style: {border: '5px solid green', color: 'red'}},
  {innerHTML: 'Hello world!'});

Merge arrays and objects. Note that undefined can be used to preserv values in the lefthand array/object.

o = mergeRecursive({a:'a'}, [1,2,3], [undefined, null, [30,31]], {a:undefined, b:'b'});
// o = {0:1, 1:null, 2:[30,31], a:'a', b:'b'}

Any argument not beeing a JavaScript object (including null) will be ignored. Except for the first argument, also DOM nodes are discarded. Beware that ie strings, created like new String() are in fact objects.

o = mergeRecursive({a:'a'}, 1, true, null, undefined, [1,2,3], 'bc', new String('de'));
// o = {0:'d', 1:'e', 2:3, a:'a'}

If you want to merge two objects into a new (without affecting any of the two) supply {} as first argument

var a={}, b={b:'abc'}, c={c:'cde'}, o;
o = mergeRecursive(a, b, c);
// o===a is true, o===b is false, o===c is false

Edit (by ReaperSoon):

सरणी मर्ज करने के लिए

function mergeRecursive(obj1, obj2) {
  if (Array.isArray(obj2)) { return obj1.concat(obj2); }
  for (var p in obj2) {
    try {
      // Property in destination object set; update its value.
      if ( obj2[p].constructor==Object ) {
        obj1[p] = mergeRecursive(obj1[p], obj2[p]);
      } else if (Array.isArray(obj2[p])) {
        obj1[p] = obj1[p].concat(obj2[p]);
      } else {
        obj1[p] = obj2[p];
      }
    } catch(e) {
      // Property in destination object not set; create it and set its value.
      obj1[p] = obj2[p];
    }
  }
  return obj1;
}

It's worth mentioning that the version from the 140byt.es collection is solving the task within minimum space and is worth a try for this purpose:

कोड:

function m(a,b,c){for(c in b)b.hasOwnProperty(c)&&((typeof a[c])[0]=='o'?m(a[c],b[c]):a[c]=b[c])}

Usage for your purpose:

m(obj1,obj2);

Here's the original Gist .


With Underscore.js , to merge an array of objects do:

var arrayOfObjects = [ {a:1}, {b:2, c:3}, {d:4} ];
_(arrayOfObjects).reduce(function(memo, o) { return _(memo).extend(o); });

It results in:

Object {a: 1, b: 2, c: 3, d: 4}

आप मेरी विधि का पालन करके वस्तुओं को मर्ज कर सकते हैं

var obj1 = { food: 'pizza', car: 'ford' };
var obj2 = { animal: 'dog' };

var result = mergeObjects([obj1, obj2]);

console.log(result);
document.write("result: <pre>" + JSON.stringify(result, 0, 3) + "</pre>");

function mergeObjects(objectArray) {
    if (objectArray.length) {
        var b = "", i = -1;
        while (objectArray[++i]) {
            var str = JSON.stringify(objectArray[i]);
            b += str.slice(1, str.length - 1);
            if (objectArray[i + 1]) b += ",";
        }
        return JSON.parse("{" + b + "}");
    }
    return {};
}


मरे तरीके:

function mergeObjects(defaults, settings) {
    Object.keys(defaults).forEach(function(key_default) {
        if (typeof settings[key_default] == "undefined") {
            settings[key_default] = defaults[key_default];
        } else if (isObject(defaults[key_default]) && isObject(settings[key_default])) {
            mergeObjects(defaults[key_default], settings[key_default]);
        }
    });

    function isObject(object) {
        return Object.prototype.toString.call(object) === '[object Object]';
    }

    return settings;
}

:)








javascript-objects