2012-09-07 14 views
12

Szukam sposobu, aby połączyć dwie konfiguracje obiektów razem, coś jak:Coś jak jQuery.extend(), ale samodzielne?

var developmentConfig = { 
    url: "localhost", 
    port: 80 
}; 

var productionConfig = { 
    url: "example.com" 
}; 

var config = isDevelopment ? developmentConfig : jQuery.extend(developmentConfig, productionConfig); 

jednak jest to aplikacja node.js i nie chcę, aby to jQuery i szukam czegoś podobnego ale samodzielny. Wiem, że mógłbym napisać coś podobnego sobie, ale wolałbym użyć czegoś sprawdzone (istnieją przypadki brzegowe, powikłania gdy obiekty config korzystać bogatsze hierarchie etc.)

Edytuj: Prosty iteracja nie wystarczy, bo to nie obsługuje struktur hierarchicznych. Ani też Underscore's extend.

+4

wykorzystywać źródła, Luke :) – epoch

+2

Jest strona, która naprawdę pomaga w kontroli źródła jQuery. Dla 'jQuery.extend', [tutaj] (http://james.padolsey.com/jquery/#v=git&fn=jQuery.extend). –

+1

Przed pytaniem zwróciłem uwagę, ale istnieją zewnętrzne zależności od funkcji extend(), więc jest więcej pracy do zrobienia, niż skopiowanie kilku linii. – Borek

Odpowiedz

18

Jeśli wszystko, czego potrzebujesz, to rozszerzenie, to bardzo łatwo jest to napisać w kilku linijkach. Jeśli chcesz rekurencyjne rozszerzenie, jest to trudne do zrobienia, że ​​zupełnie ogólnie, jeśli chcesz mieć struktury koliste, obiektów złożonych łańcuchów prototypów itp jeśli to tylko niektóre zagnieżdżone zwykłe przedmioty, to powinno działać:

function extend (target, source) { 
    target = target || {}; 
    for (var prop in source) { 
    if (typeof source[prop] === 'object') { 
     target[prop] = extend(target[prop], source[prop]); 
    } else { 
     target[prop] = source[prop]; 
    } 
    } 
    return target; 
} 

Jeśli "szukam lekkiej biblioteki, która to robi (bez rekursji, z powodów wymienionych powyżej) i innych podobnych funkcji, których nie zapewnia javascript, spójrz na Underscore, która jest również dostępna przez NPM dla węzła.

+0

Potrzebuję również zachowania rekurencyjnego, zobacz pytanie. – Borek

+0

@Borek Zaktualizowałem teraz odpowiedź – nickf

+3

spowoduje to również konwersję tablic na obiekty. –

4

Jeszcze jeden przykład z prostej funkcji autonomicznej dla przyszłych pielgrzymów w całej tej sprawie z ochroną od seryjnej właściwości różnych typów:

function extend(obj) { 
    Array.prototype.slice.call(arguments, 1).forEach(function(source) { 
     if (source) { 
      for (var prop in source) { 
       if (source[prop].constructor === Object) { 
        if (!obj[prop] || obj[prop].constructor === Object) { 
         obj[prop] = obj[prop] || {}; 
         extend(obj[prop], source[prop]); 
        } else { 
         obj[prop] = source[prop]; 
        } 
       } else { 
        obj[prop] = source[prop]; 
       } 
      } 
     } 
    }); 
    return obj; 
} 

Zastosowanie:

extend({ name:'Maria', address:{ city:'Moscow', street:'Lenina str, 52' } }, { name:'Marianna', address:{ zip:1200003 }}) 
=> { name:'Marianna', address:{ city:'Moscow', street:'Lenina str, 52', zip:1200003 } } 
+0

najpierw "jeśli" w "dla": source [prop]! == null && source [prop] .constructor === Object –

1

Rozwiązanie to tworzy nowy obiekt i jest w stanie obsłużyć wiele obiektów .

Ponadto jest rekurencyjne i możesz wybrać pogodę chcesz do nadpisywania Wartości i obiektów.

function extendObjects() { 

     var newObject  = {}; 
     var overwriteValues = false; 
     var overwriteObjects = false; 

     for (var indexArgument = 0; indexArgument < arguments.length; indexArgument++) { 

      if (typeof arguments[indexArgument] !== 'object') { 

       if (arguments[indexArgument] == 'overwriteValues_True') { 

        overwriteValues = true;    
       } else if (arguments[indexArgument] == 'overwriteValues_False') { 

        overwriteValues = false;        
       } else if (arguments[indexArgument] == 'overwriteObjects_True') { 

        overwriteObjects = true;  
       } else if (arguments[indexArgument] == 'overwriteObjects_False') { 

        overwriteObjects = false; 
       } 

      } else { 

       extendObject(arguments[indexArgument], newObject, overwriteValues, overwriteObjects); 
      } 

     } 

     function extendObject(object, extendedObject, overwriteValues, overwriteObjects) { 

      for (var indexObject in object) { 

       if (typeof object[indexObject] === 'object') { 

        if (typeof extendedObject[indexObject] === "undefined" || overwriteObjects) { 
         extendedObject[indexObject] = object[indexObject]; 
        } 

        extendObject(object[indexObject], extendedObject[indexObject], overwriteValues, overwriteObjects); 

       } else { 

        if (typeof extendedObject[indexObject] === "undefined" || overwriteValues) { 
         extendedObject[indexObject] = object[indexObject]; 
        } 

       } 

      }  

      return extendedObject; 

     } 

     return newObject; 
    } 

    var object1   = { a : 1, b : 2, testArr : [888, { innArr : 1 }, 777 ], data : { e : 12, c : { lol : 1 }, rofl : { O : 3 } } }; 
    var object2   = { a : 6, b : 9, data : { a : 17, b : 18, e : 13, rofl : { O : 99, copter : { mao : 1 } } }, hexa : { tetra : 66 } }; 
    var object3   = { f : 13, g : 666, a : 333, data : { c : { xD : 45 } }, testArr : [888, { innArr : 3 }, 555 ] }; 

    var newExtendedObject = extendObjects('overwriteValues_False', 'overwriteObjects_False', object1, object2, object3); 

Zawartość newExtendedObject:

{"a":1,"b":2,"testArr":[888,{"innArr":1},777],"data":{"e":12,"c":{"lol":1,"xD":45},"rofl":{"O":3,"copter":{"mao":1}},"a":17,"b":18},"hexa":{"tetra":66},"f":13,"g":666} 

Fiddle: http://jsfiddle.net/o0gb2umb/

Powiązane problemy