ජාවාස්ක්‍රිප්ට් වස්තු දෙකක ගුණාංග ගතිකව ඒකාබද්ධ කරන්නේ කෙසේද?


2531

ධාවන වේලාවේදී (ඉතා සරල) ජාවාස්ක්‍රිප්ට් වස්තු දෙකක් ඒකාබද්ධ කිරීමට මට හැකියාව තිබිය යුතුය. උදාහරණයක් ලෙස මම කැමතියි:

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

obj1.merge(obj2);

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

යමෙකුට මේ සඳහා පිටපතක් තිබේද? නැතහොත් මෙය සිදු කිරීම සඳහා ගොඩනගා ඇති ක්‍රමයක් ගැන දන්නවාද? මට පුනරාවර්තනයක් අවශ්‍ය නොවන අතර, කාර්යයන් ඒකාබද්ධ කිරීමට මට අවශ්‍ය නැත, පැතලි වස්තු පිළිබඳ ක්‍රම පමණි.


සමාන පිළිතුරක් මත මෙම පිළිතුර සඳහන් කිරීම වටී , එය “එක් මට්ටමක් පහළට” ඒකාබද්ධ කරන්නේ කෙසේදැයි පෙන්වයි. එනම්, එය අනුපිටපත් යතුරු වල අගයන් ඒකාබද්ධ කරයි (පළමු අගය දෙවන අගය සමඟ නැවත ලිවීම වෙනුවට), නමුත් ඊට වඩා වැඩි ප්‍රතිලාභයක් නොලැබේ. IMHO, එම කාර්යය සඳහා එහි හොඳ පිරිසිදු කේතය.
මෙවලම් සාදන්නා ස්ටීව්

BTW, ඉහළම පිළිතුරු කිහිපය "නොගැඹුරු" ඒකාබද්ධ කිරීමක් කරයි: එකම යතුර obj1 සහ obj2 යන දෙකෙහිම තිබේ නම්, obj2 හි අගය තබා ඇත, obj1 හි අගය පහත වැටේ. උදා: ප්‍රශ්නයේ උදාහරණය තිබේ නම් var obj2 = { animal: 'dog', food: 'bone' };, ඒකාබද්ධ කිරීම වනු ඇත { food: 'bone', car: 'ford', animal: 'dog' }. ඔබ "කැදැලි දත්ත" සමඟ වැඩ කරන්නේ නම් සහ "ගැඹුරු ඒකාබද්ධ කිරීමක්" අවශ්‍ය නම්, "ගැඹුරු ඒකාබද්ධ කිරීම" හෝ "පුනරාවර්තනය" සඳහන් පිළිතුරු සොයන්න. ඔබට සාරධර්ම තිබේ නම් arrays, මෙහි සඳහන් කර ඇති පරිදි "ග්‍රේබ්" ටෙහ්ෂ්‍රයික් / ඩෙප්මර්ජ් "විකල්පය භාවිතා කරන්න .
මෙවලම් සාදන්නා ස්ටීව්

කරුණාකර සබැඳිය පහත අනුගමනය stackoverflow.com/questions/171251/... මෙම ES6 අනුවාදය නව ලක්ෂණය වන පැතිරීම ක්රියාකරු
Dev216

Answers:


2931

ECMAScript 2018 සම්මත ක්‍රමය

ඔබ වස්තු පැතිරීම භාවිතා කරනු ඇත :

let merged = {...obj1, ...obj2};

mergedදැන් obj1සහ obj2. තුළ ඇති ගුණාංග එහි ඇති obj2අය නැවත ලියයි obj1.

/** There's no limit to the number of objects you can merge.
 *  Later properties overwrite earlier properties with the same name. */
const allRules = {...obj1, ...obj2, ...obj3};

මෙන්න මෙම සින්ටැක්ස් සඳහා MDN ප්‍රලේඛනය . ඔබ බාබෙල් භාවිතා කරන්නේ නම් ඔබට බාබල්-ප්ලගීන-ට්‍රාන්ස්ෆෝමර්-වස්තු-විවේකය අවශ්‍ය වේ ප්ලගිනය අවශ්‍ය වේ.

ECMAScript 2015 (ES6) සම්මත ක්‍රමය

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

( MDN JavaScript යොමුව බලන්න )


ES5 සහ ඊට පෙර ක්‍රමය

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

මෙම සරල සියලු ගුණාංග එකතු කරන බව සටහන obj2වෙත obj1ඔබ තවමත් අනූන භාවිතා කිරීමට අවශ්ය නම්, ඔබ අවශ්ය දේ විය නොහැකි විය obj1.

ඔබ ඔබේ මූලාකෘති පුරා විසිරී ඇති රාමුවක් භාවිතා කරන්නේ නම්, එවිට ඔබට චෙක්පත් වැනි රසිකයින් ලබා ගත යුතුය 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;
}

90
වස්තූන්ට එකම නාම ලක්ෂණ තිබේ නම් මෙය ක්‍රියා නොකරයි, තවද ඔබට ගුණාංග ඒකාබද්ධ කිරීමට අවශ්‍ය වනු ඇත.
Xiè Jiléi

69
මෙය සිදු කරන්නේ නොගැඹුරු පිටපතක් / ඒකාබද්ධ කිරීමක් පමණි. මූලද්රව්ය රාශියක් ක්ලෝබර් කිරීමේ හැකියාව ඇත.
ජේ ටේලර්

45
+1 සමහර දුප්පත් ආත්මයන්ට ඔවුන්ගේ මූලාකෘති පුරාම රාමු භාවිතා කිරීමට බල කෙරී ඇති බව පිළිගැනීම සඳහා ...
thejonwithnoh

4
"එබැවින් එය නව දේපල පිටපත් කිරීම හෝ නිර්වචනය කිරීමට එදිරිව ගුණාංග පවරයි. ඒකාබද්ධ කිරීමේ ප්‍රභවයන් ලබා ගන්නන් සිටී නම් නව ගුණාංග මූලාකෘතියකට ඒකාබද්ධ කිරීම නුසුදුසු වනු ඇත." ( developper.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ). මට පාවිච්චි කරන්න සිද්ධ වුණා var merged = {...obj1, ...obj2}.
මෝර්ග්ලර්

2
@ Ze'ev{...obj1, ...{animal: 'dog'}}
backslash112

1192

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" }

ඉහත කේතය, විකෘති ඇත දැනට පවතින වස්තුවක් ලෙස නම් settings.


තර්කය වෙනස් නොකර නව වස්තුවක් නිර්මාණය කිරීමට ඔබට අවශ්‍ය නම් , මෙය භාවිතා කරන්න:

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.

166
ප්‍රවේශම් වන්න: විචල්ය "සැකසුම්" වෙනස් කරනු ඇත. jQuery නව අවස්ථාවක් ලබා නොදේ. මෙයට හේතුව (සහ නම් කිරීම සඳහා) .extend () සංවර්ධනය කර ඇත්තේ දේවල් එකට එකතු කිරීම වෙනුවට වස්තූන් දිගු කිරීම සඳහා ය. ඔබට නව වස්තුවක් අවශ්‍ය නම් (උදා: සැකසීම් ඔබට ස්පර්ශ කිරීමට අවශ්‍ය නොවන පෙරනිමි), ඔබට සැමවිටම jQuery.extend ({}, සැකසුම්, විකල්ප);
වෙබ්මාට්

1
හරි! ගොඩක් ස්තුතියි. කලින් අදහස් දැක්වූ පරිදි එය දුර්වල ලෙස නම් කර ඇත. මම jQuery ලියකියවිලි පසුපසට සහ හතරවනුව සෙව්වා.
මයික් ස්ටාරොව්

28
මතක තබා ගන්න, jQuery.extend හි ගැඹුරු (බූලියන්) පසුබිමක් ද ඇත. jQuery.extend(true,settings,override), සැකසුම් වල ඇති දේපලක් වස්තුවක් රඳවාගෙන අභිබවා ගියහොත් එය වැදගත් වන්නේ එම වස්තුවේ කොටසක් පමණි. අසමසම ගුණාංග ඉවත් කරනවා වෙනුවට ගැඹුරු සැකසුම යාවත්කාලීන වන්නේ එය පවතින තැනට පමණි. පෙරනිමිය වැරදිය.
vol7ron

19
ගී කැමැත්ත කරන්නන්, ඔවුන් මෙය නම් කිරීම සඳහා හොඳ කාර්යයක් කළා. ඔබ ජාවාස්ක්‍රිප්ට් වස්තුවක් දිගු කරන්නේ කෙසේදැයි සොයන්නේ නම් එය වහාම පැමිණේ! ඔබ ජාවාස්ක්‍රිප්ට් වස්තූන් විලයනය කිරීමට හෝ මැසීමට උත්සාහ කරන්නේ නම් ඔබට එයට පහර නොදෙනු ඇත.
ඩෙරෙක් ග්‍රීර්

2
වැනිලා ජේඑස් පේළි කිහිපයක් තමන්ට අවශ්‍ය දේ කරන විට පුස්තකාල ක්‍රමයක් භාවිතා කිරීම ගැන සලකා බලන ලෙස මිනිසුන්ට නොකියන්න. JQuery ට පෙර කාලයක් තිබුණි!
CrazyMerlin

348

මෙම එකමුතු සම්මතයන් 2015 (ES6) නිශ්චිතව දක්වා Object.assignමේ වනු ඇත.

Object.assign(obj1, obj2);

වත්මන් බ්‍රව්සර් සහාය හොඳ අතට හැරෙමින් පවතී , නමුත් ඔබ සහාය නොමැති බ්‍රව්සර් සඳහා සංවර්ධනය කරන්නේ නම්, ඔබට පොලිෆිල් එකක් භාවිතා කළ හැකිය .


35
මෙය නොගැඹුරු ඒකාබද්ධ කිරීමක් පමණක් බව සලකන්න
ජෝකිම් ලූස්

මම හිතන්නේ මේ අතර Object.assignහොඳ ආවරණයක් තිබේ: kangax.github.io/compat-table/es6/…
ලේසර් බාස්

13
මෙය දැන් නිවැරදි පිළිතුර විය යුතුය. මේ දිනවල මිනිසුන් තම කේතය සම්පාදනය කරන්නේ මේ ආකාරයේ දේට සහාය නොදක්වන දුර්ලභ බ්‍රව්සරයට (IE11) අනුකූල වීම සඳහා ය. පැති සටහන: ඔබට obj1 වෙත obj2 එක් කිරීමට අවශ්‍ය නැතිනම්, ඔබට නව වස්තුවක් භාවිතා කර ආපසු Object.assign({}, obj1, obj2)
එවිය

6
U දූරායි මා දුටු වාර්තාවලට අනුව, 2016 ජූලි වන විට
IE11

3
Erman කර්මනි OP විශේෂයෙන් පෙන්වා දෙන්නේ පුනරාවර්තනය අනවශ්‍ය බවයි. එමනිසා, මෙම විසඳුම නොගැඹුරු ඒකාබද්ධ කිරීමක් සිදු කරන බව දැන ගැනීම ප්‍රයෝජනවත් වන අතර, මෙම පිළිතුර ප්‍රමාණවත් වේ. ජෝකිම්ලූගේ අදහස් දැක්වීමට හොඳ පිළිගැනීමක් ලැබී ඇති අතර අවශ්‍ය විටෙක අමතර තොරතුරු සපයයි. ගැඹුරු සහ නොගැඹුරු ඒකාබද්ධ කිරීම හා සමාන මාතෘකා අතර වෙනස මෙම සාකච්ඡාවේ විෂය පථයෙන් ඔබ්බට ගොස් අනෙකුත් SO ප්‍රශ්න වලට වඩා සුදුසු යැයි මම සිතමි.
නැනෝ විශාරද

265

වස්තු ගුණාංග ඒකාබද්ධ කිරීම සඳහා මම කේතයක් ලබාගෙන මෙහි අවසන් වීමි. කෙසේ වෙතත් පුනරාවර්තන ඒකාබද්ධ කිරීම සඳහා කේතයක් නොතිබූ බැවින් මම එය ලියා තැබුවෙමි. (සමහර විට jQuery දිගුව පුනරාවර්තන BTW විය හැකිද?) කෙසේ හෝ වෙනත් කෙනෙකුට එය ප්‍රයෝජනවත් වේ යැයි බලාපොරොත්තු වෙමු.

(දැන් කේතය භාවිතා නොකරයි 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);

වස්තුව o3 වැනි නිෂ්පාදනය කරයි

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

11
හොඳයි, නමුත් මම මුලින්ම වස්තූන්ගේ ගැඹුරු පිටපතක් සාදමි. වස්තූන් යොමු කිරීමෙන් සම්මත වන බැවින් මේ ආකාරයෙන් o1 ද වෙනස් කරනු ලැබේ.
skerit

1
මම සොයන දේ මෙයයි. ඔබ උත්සාහ කිරීමේ ඇල්ලීමේ ප්‍රකාශයට යාමට පෙර obj2.hasOwnProperty (p) දැයි පරීක්ෂා කර බලන්න. එසේ නොමැතිනම්, මූලාකෘති දාමයේ ඉහළ සිට ඉහළට ඒකාබද්ධ කිරීම සඳහා ඔබට තවත් කූට උපක්‍රමයක් ලැබෙනු ඇත.
ඇඩම්

3
ස්තූතියි මාකස්. O1 ද MergeRecursive විසින් වෙනස් කරන බව සලකන්න, එබැවින් අවසානයේ o1 සහ o3 සමාන වේ. ඔබ කිසිවක් ආපසු නොදුන්නේ නම් එය වඩාත් බුද්ධිමත් විය හැකිය, එබැවින් පරිශීලකයා ඔවුන් සපයන දේ (o1) වෙනස් වී ප්‍රති .ලය බවට පත්වන බව දනී. එසේම, ඔබේ උදාහරණයේ දී, o2 හි ඇති o2 තුළට යමක් එකතු කිරීම වටී, o2 ගුණාංග o1 තුළට ඇතුළු වන බව පෙන්වීමට (පහත වෙනත් අය ඔබේ උදාහරණය පිටපත් කරන විකල්ප කේතයක් ඉදිරිපත් කර ඇත, නමුත් o2 ගුණාංග අඩංගු නොවන විට ඒවා කැඩී යයි. o1 හි - නමුත් මේ සම්බන්ධයෙන් ඔබගේ ක්‍රියා කරයි).
පෑන්කේක්

7
මෙය හොඳ පිළිතුරකි, නමුත් යුවළක් විවාදාත්මක ය: 1) කිසිදු තර්කනයක් ව්‍යතිරේක මත පදනම් නොවිය යුතුය; මෙම අවස්ථාවේ දී, විසි කරන ඕනෑම ව්‍යතිරේකයක් අනපේක්ෂිත ප්‍රති .ල සමඟ හසු වේ. 2) මුල් වස්තුව වෙනස් කර ඇති බැවින් කිසිවක් ආපසු නොපැමිණීම පිළිබඳ @ පෑන්කේක්ගේ අදහස් සමඟ මම එකඟ වෙමි. මෙහි jsFiddle උදාහරණයක් හැර තර්ක තොරව ය: jsfiddle.net/jlowery2663/z8at6knn/4 - ජෙෆ් Lowery
ජෙෆ් Lowery

3
එසේම, වස්තු සමූහයක් ඇති ඕනෑම අවස්ථාවක obj2 [p] .constructor == අරාව අවශ්‍ය වේ.
නිර්මාපකයා

175

බව සටහන underscore.jsගේ extend-method එක් නෞකාවක් මෙම කරන්නේ:

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

36
ඔබ නිර්නාමික වස්තූන් සමඟ ගනුදෙනු කරන විට මෙම උදාහරණය කදිම ය, නමුත් මෙය එසේ නොවේ නම්, විකෘති පිළිබඳ jQuery පිළිතුරු අනතුරු ඇඟවීමේ වෙබ්මාට්ගේ අදහස් මෙහි අදාළ වේ, අවධාරනය කරන්නේ ගමනාන්ත වස්තුවවිකෘති කරන බැවිනි. JQuery පිළිතුර මෙන්, මෙම විකෘතියෙන් තොරව හිස් වස්තුවකට ඒකාබද්ධ කරන්න:_({}).extend(obj1, obj2);
අබේ වොල්කර්

8
ඔබ සාක්ෂාත් කර ගැනීමට උත්සාහ කරන දේ අනුව අදාළ විය හැකි තවත් එකක් තිබේ: _.defaults(object, *defaults)"පෙරනිමි වස්තූන්ගේ අගයන් සමඟ වස්තුවෙහි ශුන්‍ය හා නිර්වචනය නොකළ ගුණාංග පුරවා වස්තුව ආපසු ලබා දෙන්න."
conny

ගමනාන්ත වස්තුව විකෘති කිරීම පිළිබඳව බොහෝ අය අදහස් දක්වා ඇත, නමුත් ක්‍රමවේදයක් නව එකක් නිර්මාණය කරනවාට වඩා පොදු රටාවක් (නිදසුනක් ලෙස ඩෝජෝ හි) dojo.mixin (dojo.clone (myobj), {newpropertys: “එකතු කිරීම to myobj "})
කොලින් ඩී

7
අන්ඩර්ස්කෝර්ට අත්තනෝමතික වස්තු සංඛ්‍යාවක් ගත හැකි අතර, එසේ කිරීමෙන් ඔබට මුල් වස්තුව විකෘති වීම වළක්වා ගත හැකිය var mergedObj = _.extend({}, obj1, obj2).
lobati

84

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

1
@naXa මම හිතන්නේ ඔබට මෙම fn සඳහා ලිබ් එකක් එකතු කිරීමට අවශ්‍ය නැතිනම් එය විකල්පයක් වනු ඇත.
juanmf

67

මට අද වස්තු ඒකාබද්ධ කිරීමට අවශ්‍යයි, මෙම ප්‍රශ්නය (සහ පිළිතුරු) මට බොහෝ උපකාර විය. මම සමහර පිළිතුරු අත්හදා බැලුවෙමි, නමුත් ඒ කිසිවක් මගේ අවශ්‍යතාවන්ට නොගැලපේ, එබැවින් මම පිළිතුරු කිහිපයක් ඒකාබද්ධ කර, මා විසින්ම යමක් එකතු කර නව ඒකාබද්ධ කිරීමේ කාර්යයක් ඉදිරිපත් කළෙමි. මේ තියෙන්නේ:

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

3
හොඳ පිළිතුරක් නමුත් මම සිතන්නේ පළමු හා දෙවන දේවල දේපලක් තිබේ නම් සහ ඔබ පළමු හා දෙවන ඒකාබද්ධ කිරීමෙන් නව වස්තුවක් සෑදීමට උත්සාහ කරන්නේ නම් පළමු වස්තුවෙහි ඇති අද්විතීය ඒවා නැති වී යනු ඇත
ස්ට්‍රයිකර්ස්

2
නමුත් එය අපේක්ෂිත හැසිරීම නොවේද? මෙම ශ්‍රිතයේ අරමුණ තර්ක අනුපිළිවෙලින් අගයන් ඉක්මවා යාමයි. ඊළඟට ධාරාව අභිබවා යනු ඇත. අද්විතීය අගයන් ආරක්ෂා කරන්නේ කෙසේද? මගේ උදාහරණයෙන් ඔබ බලාපොරොත්තු වන්නේ merge({}, t1, { key1: 1 })කුමක්ද?
එමරේ අර්කාන්

මගේ අපේක්ෂාව වන්නේ වස්තු-ටයිප් නොකළ අගයන් පමණක් ඒකාබද්ධ කිරීමයි.
AGamePlayer

අපේක්ෂිත ප්‍රති result ලය
Ceremcem

මෙය මගේ node.js ව්‍යාපෘතිය සඳහා දැඩි ආකාරයකින් ක්‍රියාත්මක විය. මෙතෙක්, මෙම ලිපියේ හොඳම පිළිතුර මෙයයි.
klewis

48

ඔබට වස්තු පැතිරීමේ ගුණාංග භාවිතා කළ හැකිය - වර්තමානයේ අදියර 3 ECMAScript යෝජනාව.

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

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


බ්‍රව්සර් සහාය?
ඇල්ෆ් දේව්

1
@ Alph.Dev ඔබ caniuse.com දන්නවාද?
Connexo

මට 3 තිත් සින්ටැක්ස් node.js හි වැඩ කිරීමට ලබා ගත නොහැක. node ඒ ගැන පැමිණිලි කරයි.
klewis

41

මෙම විසඳුම් ලබා පරීක්ෂා කිරීමට වෙනස් විය යුතුය source.hasOwnProperty(property)තුළ for..inපැවරීම පෙර වළළු - එසේ නැත්නම්, ඔබ කලාතුරකින් අපේක්ෂිත වන මුළු මූලාකෘති දාම, ගුණ පිටපත් අවසන් ...


40

කේතයේ එක් පේළියක N වස්තු වල ගුණාංග ඒකාබද්ධ කරන්න

Object.assignක්රමය සම්මතයන් 2015 (ES6) සම්මත කොටසක් වන අතර, ඔබට අවශ්ය දේ හරියටම කරනවා. ( IEසහාය නොදක්වයි)

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

Object.assign () ක්‍රමය භාවිතා කරනුයේ සියළුම ගණනය කළ හැකි දේපලවල අගයන් ප්‍රභව වස්තු එකක් හෝ වැඩි ගණනක සිට ඉලක්කගත වස්තුවකට පිටපත් කිරීමට ය.

වැඩිදුර කියවන්න...

මෙම polyfill පැරණි බ්රව්සර සහාය:

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

පැරණි බ්‍රව්සරයේ 'දැඩි ලෙස භාවිතා කරන්නේ කුමක්ද' හෝ එය කිසිසේත් පවතින්නේ ඇයි. වස්තුවට සහය දක්වන බ්‍රව්සර් [නිර්වචනය කිරීම; යතුරු; getOwnPropertyDescriptor; ආදිය], හරියටම පැරණි නොවේ. ඒවා gen.5 යූඒඒ හි පෙර සංස්කරණ පමණි.
බෙකිම් බකාජ්

පැහැදිලි කිරීම සඳහා ස්තූතියි Objects.assign, අනෙක් පිළිතුරු නොලැබෙන ඒකාබද්ධ වස්තුවක් ලබා දෙයි. එය වඩාත් ක්‍රියාකාරී ක්‍රමලේඛ විලාසය.
ශ්‍රීධර් සර්නොබත්

36

පහත දැක්වෙන දෙක හොඳ ආරම්භක ලක්ෂ්‍යයක් විය හැකිය. එම විශේෂ අවශ්‍යතා සඳහා ලොඩාෂ් හි අභිරුචිකරණ ශ්‍රිතයක් ද ඇත!

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


4
ඉහත ක්‍රම මගින් මුල් වස්තුව විකෘති වන බව කරුණාවෙන් සලකන්න.
Wtower

ලොඩාෂ් ක්‍රමය මට වැඩ කළේ වස්තූන් දෙකක් ඒකාබද්ධ කර දේපල රඳවා තබා ගැනීමට අවශ්‍ය වූ නිසා මට්ටම් එකක් හෝ දෙකක් ගැඹුරට (ඒවා ප්‍රතිස්ථාපනය / පිසදැමීමට වඩා).
සැම්බ්‍රික්

සත්‍ය @Wtower. මේ නිසා දෝෂයක් ඇතිවිය. එය සැමවිටම _.merge ({}, ...
මාටින් ක්‍රෙමර්

29

මාර්ගය වන විට, ඔබ සියල්ලන්ම කරන්නේ දේපල නැවත ලිවීම මිස ඒකාබද්ධ කිරීම නොවේ ...

ජාවාස්ක්‍රිප්ට් වස්තු ප්‍රදේශය සැබවින්ම ඒකාබද්ධ වූයේ එලෙස ය: toවස්තූන් නොවන වස්තූන්ගේ යතුරු පමණක් නැවත ලියනු ලැබේ from. අනෙක් සියල්ල සැබවින්ම ඒකාබද්ධ වනු ඇත . ඇත්ත වශයෙන්ම ඔබට මෙම හැසිරීම වෙනස් කළ හැක්කේ එසේ නම් පමණක් පවතින කිසිවක් නැවත ලිවීමට නොවේ 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);

3
මට ගොඩක් උදව් කළා, අවධාරනය කරන ලද js
දිගුව

1
ටයිප් ඔෆ් අරාව සහ ටයිප් ඕෆ් ශුන්‍යය 'වස්තුව' ආපසු ගෙන මෙය බිඳ දමනු ඇති බව සඳහන් කිරීම වටී.
සලාකර්

answer u01jmg3 මගේ පිළිතුර මෙතැනින් බලන්න: stackoverflow.com/questions/27936772/… - isObject function
Salakar

ඔබ භාවිතා කරන්නේ නම් node.js ව්‍යාපෘති සඳහා මෙය දැඩි ලෙස ක්‍රියාත්මක වේ
klewis

28

මෙන්න මගේ පිහිය

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

මෙම පිටුවෙන් මා පරීක්ෂා කළ අනෙක් අය සමඟ සසඳන විට, මෙම ශ්‍රිතය සැබවින්ම පුනරාවර්තන වේ (ගැඹුරු ඒකාබද්ධ කිරීමක් කරයි) සහ jQuery.extend () හොඳින් කරන දේ අනුකරණය කරයි. කෙසේ වෙතත්, පළමු වස්තුව / තර්කය වෙනස් කිරීම වඩා හොඳය, එවිට පරිශීලකයාට හිස් {}පරාමිතියක් පළමු පරාමිතිය ලෙස සම්මත කිරීමට අවශ්‍යද නැතිනම් ශ්‍රිතය මුල් වස්තුව වෙනස් කළ යුතුද යන්න තීරණය කළ හැකිය . ඒ නිසා ඔබ වෙනස් නම් dst = {}කිරීමට dst = arguments[0]එය ඔබ, අලුතින් ඒකාබද්ධ වස්තුව වෙත ගමන් පළමු වස්තුව වෙනස් වනු ඇත
Jasdeep Khalsa

3
දැන් එය ක්‍රෝම් වල වැඩ කිරීම නවතා දමා ඇත. toString.call(src) == '[object Object]'වස්තුවක් තිබේද නැද්ද යන්න පරීක්ෂා කිරීම සඳහා එවැනි ඉදිකිරීම් භාවිතා කිරීම නරක අදහසක් යැයි මම සිතමි . typeof srcවඩා හොඳයි. එපමණක් නොව එය අරා වස්තුවක් බවට පරිවර්තනය කරයි (අවම වශයෙන් මට එවැනි ක්‍රෝම් නවතම ක්‍රෝම් මත තිබේ).
m03geek

ගිජු පුඩුවක් තුළ මට මෙය කිරීමට අවශ්‍ය විය, මම මේ දක්වා භාවිතා කර ඇති VS මෙම ශ්‍රිතය මිණුම් සලකුණු කර ඇත _ ලොජ් (_ අවධාරනය කරන්න (වස්තුව, [ප්‍රභවයන්)) ස්තූතියි යාළුවා.
ආර්නාඩ් බුචොට්

20

Object.assign ()

ECMAScript 2015 (ES6)

මෙය ECMAScript 2015 (ES6) ප්‍රමිතියේ කොටසක් වන නව තාක්‍ෂණයකි. මෙම තාක්ෂණයේ පිරිවිතරයන් අවසන් කර ඇත, නමුත් විවිධ බ්‍රව්සර්වල භාවිතය සහ ක්‍රියාත්මක කිරීමේ තත්වය සඳහා අනුකූලතා වගුව පරීක්ෂා කරන්න.

Object.assign () ක්‍රමය භාවිතා කරනුයේ සියළුම ගණනය කළ හැකි දේපලවල අගයන් ප්‍රභව වස්තු එකක් හෝ වැඩි ගණනක සිට ඉලක්කගත වස්තුවකට පිටපත් කිරීමට ය. එය ඉලක්කගත වස්තුව ආපසු ලබා දෙනු ඇත.

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.

19

එතරම් සංකීර්ණ නොවන වස්තු සඳහා ඔබට 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_/

මෙම උදාහරණයේ දී "} {" නූලක් තුළ නොවිය යුතු බව මතක තබා ගන්න!


4
var so1 = JSON.stringify(obj1); var so2 = JSON.stringify(obj1); objMerge = so1.substr(0, so1.length-1)+","+so2.substr(1); console.info(objMerge);
ක්වාමිස්

function merge(obj1, obj2) { return JSON.parse((JSON.stringify(obj1) + JSON.stringify(obj2)) .replace(/\}\{/g, ',').replace(/,\}/g, '}').replace(/\{,/g, '{')); }
ඇලෙක්ස් ඉවාසියුව්

හෝ එක් ලයිනර් ලෙස:objMerge = JSON.parse((JSON.stringify(obj1) + JSON.stringify(obj2)).replace(/\}\{/, ", "));
රබ්බි ෂුකි ගුර්

1
Har චාර්ල්ස්, කණගාටුයි නමුත් "මෙම ක්‍රමය ඉතා භයානක" වන්නේ කෙසේද යන්නත් විනෝදජනකයි - මෙය ආරක්ෂිතම වේ පළමුවැන්න එය JSON භාවිතා කරන්නේ වස්තු අන්තර්ගතය අධික ලෙස ඔසවා තැබීම සඳහා ය, දෙවනුව, එය JSON වස්තුව භාවිතා කරන අතර එය සෑම අතින්ම ආරක්ෂිත වේ JSON අනුකූල වස්තු නූලකින් JSO නැවත ප්‍රතිස්ථාපනය කිරීම සඳහා යන්ත්‍රය ප්‍රශස්ත කර ඇත. තවද එහි ප්‍රමිතිය ක්‍රියාත්මක කළ පළමු බ්‍රව්සරය වන IE8 සමඟ පසුගාමී අනුකූල වේ. එය මා පුදුමයට පත් කරන්නේ "ඇයි අනේ ඇයි ඔබට මෙතරම් මෝඩ දෙයක් කියන්නට සිදු වූයේ?"
බෙකිම් බකාජ්

දැඩි ලෙස භාවිතා කළ නොහැකි බැවින් වස්තුවෙහි කාර්යයන් මෙහි බිඳ වැටෙනු ඇතැයි මම විශ්වාස කරමි, නමුත් අපට වෙනත් අවාසි පැහැදිලි කළ හැකිද?
ඔව්ඩික්සන්

18

GitHub හි පුස්තකාලයක් deepmergeඇත : එය යම් කම්පනයකට ලක්වන බවක් පෙනේ. එය තනිවම, එන්පීඑම් දෙකම හරහා ලබා ගත හැකිය සහ බෝවර් පැකේජ කළමණාකරුවන් .

පිළිතුරු වලින් කේත පිටපත් කිරීම වෙනුවට මෙය භාවිතා කිරීමට හෝ වැඩිදියුණු කිරීමට මම නැඹුරු වෙමි.


17

මෙය කිරීමට ඔබට ඇති හොඳම ක්‍රමය නම් Object.defineProperty භාවිතා කර ගණනය කළ නොහැකි නිසි දේපලක් එක් කිරීමයි.

මේ ආකාරයට ඔබ Object.prototype.extend සමඟ දේපල නිර්මාණය කරන්නේ නම් ඔබට ලැබෙනු ඇති අලුතින් නිර්මාණය කරන ලද "විස්තාරණය" නොකර ඔබේ වස්තු ගුණාංග නැවත කියවීමට ඔබට හැකි වේ.

මෙය උපකාරී වේ යැයි බලාපොරොත්තු වෙමු:

Object.defineProperty (Object.prototype, "දිගු", {
    ගණන් කළ නොහැකි: අසත්‍ය,
    අගය: ශ්‍රිතය (සිට) {
        var props = Object.getOwnPropertyNames (වෙතින්);
        var dest = මෙය;
        props.forEach (ශ්‍රිතය (නම) {
            if (නමෙහි නම) {
                var destination = Object.getOwnPropertyDescriptor (සිට, නම);
                Object.defineProperty (dest, name, destination);
            }
        });
        මෙය ආපසු දෙන්න;
    }
});

ඔබට එය ක්‍රියාත්මක වූ පසු, ඔබට කළ හැක්කේ:

var obj = {
    නම: 'සිරස්',
    අවසන්: 'පිටාර ගැලීම'
}
var replace = {
    නම: 'තොගය'
};

obj.extend (ප්‍රතිස්ථාපනය);

මම මේ ගැන බ්ලොග් සටහනක් මෙහි ලියා ඇත: http://onemoredigit.com/post/1527191998/extending-objects-in-node-js


තත්පරයක් ඉන්න --- කේතය ක්‍රියා නොකරයි! :( වෙනත් ඒකාබද්ධ කිරීමේ ඇල්ගොරිතම සමඟ සැසඳීම සඳහා එය jsperf හි ඇතුළත් කළ අතර කේතය අසමත් වේ - ක්‍රියාකාරී දිගුව නොපවතී
ජෙන්ස් රෝලන්ඩ්

16

ඔබට සරලව jQuery භාවිතා කළ හැකිය extend

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

jQuery.extend(obj1, obj2);

දැන් obj1සියලු වටිනාකම් අඩංගු obj1හාobj2


2
obj1 හි සියලු අගයන් අඩංගු වේ, obj2 නොවේ. ඔබ පළමු වස්තුව දිගු කරයි. jQuery.extend( target [, object1 ] [, objectN ] )
රූටර්

5
මෙම ප්‍රශ්නය jQuery ගැන නොවේ. JavaScript! =
JQuery

1
මම ජාවාස්ක්‍රිප්ට් සඳහා ගූගල් කළෙමි, නමුත් මෙය වඩාත් සරල ප්‍රවේශයකි
එහ්සාන්

13

මූලාකෘතියට මෙය තිබේ:

Object.extend = function(destination,source) {
    for (var property in source)
        destination[property] = source[property];
    return destination;
}

obj1.extend(obj2) ඔබට අවශ්‍ය දේ කරනු ඇත.


6
ඔබ අදහස් කළේ Object.prototype.extend? කෙසේ වෙතත්, Object.prototype දිගු කිරීම හොඳ අදහසක් නොවේ. -1.
SolutionYogi

ඒ ගැන සිතා බලන්න, එය බොහෝ විට විය යුතු Object.prototypeහා නොවිය යුතුය Object... හොඳ අදහසක් හෝ නැත, මෙය prototype.jsරාමුව කරන්නේ එයයි , එබැවින් ඔබ එය භාවිතා කරන්නේ නම් හෝ එය මත රඳා පවතින වෙනත් රාමුවක් Object.prototypeදැනටමත් දීර් extended කරනු extendඇත.
ephemient

2
මම ඔබට වීණාව කියන්නට අදහස් නොකරමි, නමුත් එය හරි යැයි කීම නිසා prototype.js කරන්නේ දුර්වල තර්කයක්. Prototype.js ජනප්‍රිය නමුත් ජාවාස්ක්‍රිප්ට් කරන්නේ කෙසේද යන්න පිළිබඳ ආදර්ශය ඔවුන් බව එයින් අදහස් නොවේ. මූලාකෘති පුස්තකාලයේ මෙම සවිස්තරාත්මක සමාලෝචනය JS pro විසින් පරීක්ෂා කරන්න. dhtmlkitchen.com/?category=/JavaScript/&date=2008/06/17/…
SolutionYogi

7
එහි හරි හෝ වැරදි නම් ඒ ගැන සැලකිලිමත් වන්නේ කවුද? එය ක්‍රියාත්මක වන්නේ නම් එය ක්‍රියාත්මක වේ. කොන්ත්රාත්තුවක් තබා ගැනීමට, නව සේවාදායකයින් දිනා ගැනීමට හෝ නියමිත දිනට සරිලන ලෙස හැරෙන්නට පරිපූර්ණ විසඳුමක් සඳහා බලා සිටීම විශිෂ්ටයි. නොමිලේ මුදල් ක්‍රමලේඛනය කිරීමට උනන්දුවක් දක්වන ඕනෑම කෙනෙකුට මෙහි දෙන්න, එවිට ඔවුන් අවසානයේදී සියල්ල “නිවැරදි” ආකාරයෙන් කරනු ඇත.
ඩේවිඩ්

1
ඔයාලා කොහෙද හොයාගත්තේ Object.prototype? Object.extendඔබේ වස්තූන් වලට බාධා නොකරනු ඇත, එය හුදෙක් Objectවස්තුවකට ශ්‍රිතයක් අමුණයි. හා obj1.extend(obj2)ගිනි කාර්යය නිවැරදි ක්රමය නොවේ, භාවිතය Object.extend(obj1, obj2)කලෙත්
artnikpro

13

** වස්තු ඒකාබද්ධ කිරීම සරල Object.assignහෝ පැතිරීමේ ...ක්‍රියාකරු **

var obj1 = { food: 'pizza', car: 'ford' }
var obj2 = { animal: 'dog', car: 'BMW' }
var obj3 = {a: "A"}


var mergedObj = Object.assign(obj1,obj2,obj3)
 // or using the Spread operator (...)
var mergedObj = {...obj1,...obj2,...obj3}

console.log(mergedObj);

වස්තූන් දකුණේ සිට වමට ඒකාබද්ධ වේ, මෙයින් අදහස් කරන්නේ ඒවායේ දකුණට ඇති වස්තූන් ලෙස සමාන ගුණ ඇති වස්තූන් අභිබවා යනු ඇති බවයි.

මෙම උදාහරණයේ දී obj2.carඅභිබවා යයිobj1.car


12

යමෙක් ගූගල් වැසීමේ පුස්තකාලය භාවිතා කරන්නේ නම් :

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'

10

මම ඩේවිඩ් කොලියර්ගේ ක්‍රමය දීර් extended කළෙමි:

  • බහු වස්තු ඒකාබද්ධ කිරීමේ හැකියාව එකතු කරන ලදි
  • ගැඹුරු වස්තූන් සඳහා සහාය වේ
  • අභිබවා යන පරාමිතිය (අවසාන පරාමිතිය බූලියන් නම් එය අනාවරණය වේ)

අභිබවා යාම අසත්‍ය නම්, කිසිදු දේපලක් අභිබවා නොයන නමුත් නව දේපල එකතු වේ.

භාවිතය: obj.merge (ඒකාබද්ධ කරයි ... [, අභිබවා යන්න]);

මෙන්න මගේ කේතය:

Object.defineProperty(Object.prototype, "merge", {
    enumerable: false,
    value: function () {
        var override = true,
            dest = this,
            len = arguments.length,
            props, merge, i, from;

        if (typeof(arguments[arguments.length - 1]) === "boolean") {
            override = arguments[arguments.length - 1];
            len = arguments.length - 1;
        }

        for (i = 0; i < len; i++) {
            from = arguments[i];
            if (from != null) {
                Object.getOwnPropertyNames(from).forEach(function (name) {
                    var descriptor;

                    // nesting
                    if ((typeof(dest[name]) === "object" || typeof(dest[name]) === "undefined")
                            && typeof(from[name]) === "object") {

                        // ensure proper types (Array rsp Object)
                        if (typeof(dest[name]) === "undefined") {
                            dest[name] = Array.isArray(from[name]) ? [] : {};
                        }
                        if (override) {
                            if (!Array.isArray(dest[name]) && Array.isArray(from[name])) {
                                dest[name] = [];
                            }
                            else if (Array.isArray(dest[name]) && !Array.isArray(from[name])) {
                                dest[name] = {};
                            }
                        }
                        dest[name].merge(from[name], override);
                    } 

                    // flat properties
                    else if ((name in dest && override) || !(name in dest)) {
                        descriptor = Object.getOwnPropertyDescriptor(from, name);
                        if (descriptor.configurable) {
                            Object.defineProperty(dest, name, descriptor);
                        }
                    }
                });
            }
        }
        return this;
    }
});

උදාහරණ සහ පරීක්ෂණ අවස්ථා:

function clone (obj) {
    return JSON.parse(JSON.stringify(obj));
}
var obj = {
    name : "trick",
    value : "value"
};

var mergeObj = {
    name : "truck",
    value2 : "value2"
};

var mergeObj2 = {
    name : "track",
    value : "mergeObj2",
    value2 : "value2-mergeObj2",
    value3 : "value3"
};

assertTrue("Standard", clone(obj).merge(mergeObj).equals({
    name : "truck",
    value : "value",
    value2 : "value2"
}));

assertTrue("Standard no Override", clone(obj).merge(mergeObj, false).equals({
    name : "trick",
    value : "value",
    value2 : "value2"
}));

assertTrue("Multiple", clone(obj).merge(mergeObj, mergeObj2).equals({
    name : "track",
    value : "mergeObj2",
    value2 : "value2-mergeObj2",
    value3 : "value3"
}));

assertTrue("Multiple no Override", clone(obj).merge(mergeObj, mergeObj2, false).equals({
    name : "trick",
    value : "value",
    value2 : "value2",
    value3 : "value3"
}));

var deep = {
    first : {
        name : "trick",
        val : "value"
    },
    second : {
        foo : "bar"
    }
};

var deepMerge = {
    first : {
        name : "track",
        anotherVal : "wohoo"
    },
    second : {
        foo : "baz",
        bar : "bam"
    },
    v : "on first layer"
};

assertTrue("Deep merges", clone(deep).merge(deepMerge).equals({
    first : {
        name : "track",
        val : "value",
        anotherVal : "wohoo"
    },
    second : {
        foo : "baz",
        bar : "bam"
    },
    v : "on first layer"
}));

assertTrue("Deep merges no override", clone(deep).merge(deepMerge, false).equals({
    first : {
        name : "trick",
        val : "value",
        anotherVal : "wohoo"
    },
    second : {
        foo : "bar",
        bar : "bam"
    },
    v : "on first layer"
}));

var obj1 = {a: 1, b: "hello"};
obj1.merge({c: 3});
assertTrue(obj1.equals({a: 1, b: "hello", c: 3}));

obj1.merge({a: 2, b: "mom", d: "new property"}, false);
assertTrue(obj1.equals({a: 1, b: "hello", c: 3, d: "new property"}));

var obj2 = {};
obj2.merge({a: 1}, {b: 2}, {a: 3});
assertTrue(obj2.equals({a: 3, b: 2}));

var a = [];
var b = [1, [2, 3], 4];
a.merge(b);
assertEquals(1, a[0]);
assertEquals([2, 3], a[1]);
assertEquals(4, a[2]);


var o1 = {};
var o2 = {a: 1, b: {c: 2}};
var o3 = {d: 3};
o1.merge(o2, o3);
assertTrue(o1.equals({a: 1, b: {c: 2}, d: 3}));
o1.b.c = 99;
assertTrue(o2.equals({a: 1, b: {c: 2}}));

// checking types with arrays and objects
var bo;
a = [];
bo = [1, {0:2, 1:3}, 4];
b = [1, [2, 3], 4];

a.merge(b);
assertTrue("Array stays Array?", Array.isArray(a[1]));

a = [];
a.merge(bo);
assertTrue("Object stays Object?", !Array.isArray(a[1]));

a = [];
a.merge(b);
a.merge(bo);
assertTrue("Object overrides Array", !Array.isArray(a[1]));

a = [];
a.merge(b);
a.merge(bo, false);
assertTrue("Object does not override Array", Array.isArray(a[1]));

a = [];
a.merge(bo);
a.merge(b);
assertTrue("Array overrides Object", Array.isArray(a[1]));

a = [];
a.merge(bo);
a.merge(b, false);
assertTrue("Array does not override Object", !Array.isArray(a[1]));

මගේ සමානාත්මතා ක්‍රමය මෙතැනින් සොයාගත හැකිය: ජාවාස්ක්‍රිප්ට් හි වස්තු සංසන්දනය



9

දී දිගුව JS 4 එය පහත සඳහන් පරිදි සිදු කළ හැක:

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

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

ඒකාබද්ධ කිරීම (වස්තුව) බලන්න : වස්තුව .


1
EXT.Object.merge හි EXTJS-9173 දෝෂය පරෙස්සම් වන්න අවුරුදු +2 කට පසුවත් තවමත් විසඳී නොමැත
ක්‍රිස්

9

වාව් .. මෙය මම පිටු කිහිපයකින් දුටු පළමු ස්ටැක් ඕවර්ෆ්ලෝ පෝස්ට් එකයි. තවත් "පිළිතුරක්" එකතු කිරීම ගැන සමාව ඉල්ලන්න

මෙම ක්රමය සඳහා වේ ES5 සහ ඊට පෙර - ES6 ඇමතීමට වෙනත් පිළිතුරු ඕනෑ තරම් තිබේ.

දේපල උපයෝගී කර ගනිමින් කිසිදු "ගැඹුරු" වස්තුවක් මා දුටුවේ නැත arguments. මෙන්න මගේ පිළිතුර - සංයුක්ත හා පුනරාවර්තන , අසීමිත වස්තු තර්ක සම්මත කිරීමට ඉඩ දීම:

function extend() {
    for (var o = {}, i = 0; i < arguments.length; i++) {
        // if (arguments[i].constructor !== Object) continue;
        for (var k in arguments[i]) {
            if (arguments[i].hasOwnProperty(k)) {
                o[k] = arguments[i][k].constructor === Object ? extend(o[k] || {}, arguments[i][k]) : arguments[i][k];
            }
        }
    }
    return o;
}

අදහස් දක්වා ඇති කොටස අත්‍යවශ්‍ය නොවේ .. එය හුදෙක් වස්තූන් නොවන (දෝෂ වළක්වා) සම්මත කර ඇති තර්ක මඟ හරිනු ඇත.

උදාහරණයක්:

extend({
    api: 1,
    params: {
        query: 'hello'
    }
}, {
    params: {
        query: 'there'
    }
});

// outputs {api: 1, params: {query: 'there'}}

මෙම පිළිතුර දැන් සාගරයේ බින්දුවක් ...


විශිෂ්ට ලෙස ක්‍රියාත්මක වන කෙටිම පිළිතුර! එය තවත් ඉහළ නැංවීමට සුදුසුයි!
ජෙන්ස් ටර්නෙල්

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

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

JQuery.extend () භාවිතා කිරීම - සබැඳිය

// Merge obj1 & obj2 to result
var result1 = $.extend( {}, obj1, obj2 );

_.Merge () භාවිතා කිරීම - සබැඳිය

// Merge obj1 & obj2 to result
var result2 = _.merge( {}, obj1, obj2 );

_.Extend () භාවිතා කිරීම - සබැඳිය

// Merge obj1 & obj2 to result
var result3 = _.extend( {}, obj1, obj2 );

Object.assign () ECMAScript 2015 (ES6) භාවිතා කිරීම - සබැඳිය

// Merge obj1 & obj2 to result
var result4 = Object.assign( {}, obj1, obj2 );

සියල්ලන්ගේ නිමැවුම්

obj1: { animal: 'dog' }
obj2: { food: 'pizza', car: 'ford' }
result1: {food: "pizza", car: "ford", animal: "dog"}
result2: {food: "pizza", car: "ford", animal: "dog"}
result3: {food: "pizza", car: "ford", animal: "dog"}
result4: {food: "pizza", car: "ford", animal: "dog"}

7

මාකස්ගේ සහ vsync පිළිතුර මත පදනම්ව මෙය පුළුල් කළ අනුවාදයකි. ශ්‍රිතය ඕනෑම තර්ක ගණනක් ගනී. DOM හි ගුණාංග සැකසීමට එය භාවිතා කළ හැකිය නෝඩ් වල අතර අගයන්හි ගැඹුරු පිටපත් සාදයි. කෙසේ වෙතත්, පළමු තර්කය යොමු කිරීම මගින් දෙනු ලැබේ.

DOM නෝඩයක් හඳුනා ගැනීම සඳහා, isDOMNode () ශ්‍රිතය භාවිතා කරයි (Stack Overflow ප්‍රශ්නය බලන්න JavaScript isDOM - JavaScript වස්තුව DOM වස්තුවක් දැයි ඔබ පරීක්ෂා කරන්නේ කෙසේද? )

එය ඔපෙරා 11, ෆයර්ෆොක්ස් 6, ඉන්ටර්නෙට් එක්ස්ප්ලෝරර් 8 සහ ගූගල් ක්‍රෝම් 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;
}

උදාහරණ කිහිපයක්

HTML මූලද්‍රව්‍යයක අභ්‍යන්තර HTML සහ විලාසය සකසන්න

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

අරා සහ වස්තු ඒකාබද්ධ කරන්න. වම්පස අරා / වස්තුවෙහි අගයන් ආරක්ෂා කිරීමට නිර්වචනය නොකළ හැකි බව සලකන්න.

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'}

ජාවාස්ක්‍රිප්ට් වස්තුවකට නොගැලපෙන ඕනෑම තර්කයක් (ශූන්‍යය ඇතුළුව) නොසලකා හරිනු ඇත. පළමු තර්කය හැරුණු විට DOM නෝඩ් ද ඉවතලනු ලැබේ. අළුත් නූල් () මෙන් නිර්මාණය කරන ලද නූල් ඇත්ත වශයෙන්ම වස්තූන් බව පරෙස්සම් වන්න.

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

ඔබට වස්තු දෙකක් නවයකට ඒකාබද්ධ කිරීමට අවශ්‍ය නම් (මේ දෙකෙන් එකකටවත් බලපෑමක් නොකර) පළමු තර්කය ලෙස supply} සැපයුම සපයන්න

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

සංස්කරණය කරන්න (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;
}


5

ඔබ ලොඩාෂ් හි පෙරනිමි ඩීප් භාවිතා කළ යුතුය

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

5

Underscore.js සමඟ , වස්තු සමූහයක් ඒකාබද්ධ කිරීම සඳහා කරන්නේ:

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

එහි ප්‍රති results ලය:

Object {a: 1, b: 2, c: 3, d: 4}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.