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




examples tutorial (25)

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

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

obj1.merge(obj2);

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

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


Answers

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

इस प्रकार जावास्क्रिप्ट ऑब्जेक्ट एरिया वास्तव में विलय हो गया है: ऑब्जेक्ट्स में केवल कुंजियां जो ऑब्जेक्ट्स नहीं हैं, वे स्वयं से ओवरराइट की जाएंगी। बाकी सब कुछ वास्तव में विलय हो जाएगा। निस्संदेह आप इस व्यवहार को किसी भी चीज को ओवरराइट नहीं कर सकते हैं, जैसे कि 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 il = arguments.length;

  for (var i = il - 1; i > 0; --i) {
    for (var key in arguments[i]) {
      if (arguments[i].hasOwnProperty(key)) {
        arguments[0][key] = arguments[i][key];
      }
    }
  }
};

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

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


You should use lodash's defaultsDeep

_.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
// → { 'user': { 'name': 'barney', 'age': 36 } }


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

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

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

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

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 .


बस अगर कोई 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'

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

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


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}

jQuery के लिए इसके लिए एक उपयोगिता भी है: http://api.jquery.com/jQuery.extend/

JQuery दस्तावेज़ से लिया गया:

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

// Now the content of settings object is the following:
// { validate: true, limit: 5, name: "bar" }

उपरोक्त कोड ऑब्जेक्ट नाम वाली ऑब्जेक्ट को म्यूटेट करेगा।

यदि आप तर्क को संशोधित किए बिना एक नया ऑब्जेक्ट बनाना चाहते हैं, तो इसका उपयोग करें:

var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };

/* Merge defaults and options, without modifying defaults */
var settings = $.extend({}, defaults, options);

// The content of settings variable is now the following:
// {validate: true, limit: 5, name: "bar"}
// The 'defaults' and 'options' variables remained the same.

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

  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
    };
*/

मैं ऑब्जेक्ट गुणों को मर्ज करने के लिए कोड के लिए 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 } } };

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

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

jQuery.extend(obj1, obj2);

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


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

ईसीएमएस्क्रिप्ट 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;
}

हार्मनी 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 उपयोग कर सकते हैं।


Object.assign ()

ईसीएमएस्क्रिप्ट 2015 (ईएस 6)

यह एक नई तकनीक है, ईसीएमएस्क्रिप्ट 2015 (ईएस 6) मानक का हिस्सा है। इस तकनीक के विनिर्देश को अंतिम रूप दिया गया है, लेकिन विभिन्न ब्राउज़रों में उपयोग और कार्यान्वयन की स्थिति के लिए संगतता तालिका की जांच करें।

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

var o1 = { a: 1 };
var o2 = { b: 2 };
var o3 = { c: 3 };

var obj = Object.assign(o1, o2, o3);
console.log(obj); // { a: 1, b: 2, c: 3 }
console.log(o1);  // { a: 1, b: 2, c: 3 }, target object itself is changed.

निम्नलिखित दो शायद एक अच्छा प्रारंभिक बिंदु हैं। lodash भी उन विशेष जरूरतों के लिए एक customizer समारोह है!

_.extend ( underscorejs.org/#extend )
_.merge ( https://lodash.com/docs#merge )


In Ext JS 4 it can be done as follows:

var mergedObject = Ext.Object.merge(object1, object2)

// Or shorter:
var mergedObject2 = Ext.merge(object1, object2)

See merge( object ) : Object .


बहुत जटिल वस्तुओं के लिए आप JSON उपयोग कर सकते हैं:

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

objMerge = JSON.stringify(obj1) + JSON.stringify(obj2);

// {"food": "pizza","car":"ford"}{"animal":"dog","car":"chevy"}

objMerge = objMerge.replace(/\}\{/, ","); //  \_ replace with comma for valid JSON

objMerge = JSON.parse(objMerge); // { food: 'pizza', animal: 'dog', car: 'chevy'}
// Of same keys in both objects, the last object's value is retained_/

आपको याद है कि इस उदाहरण में "} {" एक स्ट्रिंग के भीतर नहीं होना चाहिए !


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

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

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

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

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


कोड:

// extends 'from' object with members from 'to'. If 'to' is null, a deep clone of 'from' is returned
function extend(from, to)
{
    if (from == null || typeof from != "object") return from;
    if (from.constructor != Object && from.constructor != Array) return from;
    if (from.constructor == Date || from.constructor == RegExp || from.constructor == Function ||
        from.constructor == String || from.constructor == Number || from.constructor == Boolean)
        return new from.constructor(from);

    to = to || new from.constructor();

    for (var name in from)
    {
        to[name] = typeof to[name] == "undefined" ? extend(from[name], null) : to[name];
    }

    return to;
}

परीक्षा:

var obj =
{
    date: new Date(),
    func: function(q) { return 1 + q; },
    num: 123,
    text: "asdasd",
    array: [1, "asd"],
    regex: new RegExp(/aaa/i),
    subobj:
    {
        num: 234,
        text: "asdsaD"
    }
}

var clone = extend(obj);






javascript javascript-objects