2009-08-26 14 views
44

Mam funkcji o nazwie „Colorbox” (jQuery plugin), które ma szereg parametrów tak:łączenie obiektów JavaScript w jedną

$(this).colorbox({ 
    width : "500px", 
    height : "500px" 
}); 

Mam kilka różnych typów „to”, choć każdy z ich własne właściwości. Tak:

var Type = { 
    video: { 
    width : "500px", 
    height : "500px" 
    }, 
    gallery: { 
    width : "1065px", 
    height : "600px" 
    } 
} 

Poza tym mam inne zachowania, logiki i „default” grupę ustawień (które zostaną zastąpione przez bardziej konkretnych z nich). Co próbuję zrobić, to nacisnąć wszystkie odpowiednie ustawienia, z wielu obiektów w jeden obiekt, więc mogę po prostu zadzwonić:

$(this).colorbox(Settings); 

Jak mogę przenieść nieznaną grupę właściwości i ich wartości (na przykład "width" i "height") z czegoś takiego jak Type.video do Ustawień? Celem jest wywołanie funkcji Settings.height i odzyskanie wartości, którą wprowadziłem.

+1

możliwe duplikat [? W jaki sposób można połączyć właściwości dwóch obiektów JavaScript dynamicznie] (http://stackoverflow.com/questions/171251/how-can-i-merge-properties -of-dwa-javascript-objects-dynamically) – givanse

+0

Proszę zobaczyć moją odpowiedź w http://stackoverflow.com/a/33572520/2934015 dla zastrzeżeń i alternatywnego rozwiązania. –

Odpowiedz

82

Spójrz na metodę JQuery extend. Może łączyć ze sobą dwa obiekty i wszystkie ich właściwości.

z przykładu stronie jQuery:

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

teraz Ustawienia zawiera scalone ustawienia i opcje obiektów.

+0

To wygląda idealnie! Sądzę, że pomyślałem, że będzie to wbudowana metoda javascript, ale Extend wydaje się robić dokładnie to, czego potrzebuję. Dzięki! –

+0

Wydaje się to przydatne dla OP, ale technicznie nie jest to, o co pyta. OP nie wspomniał, że chciał użyć jQuery do tego ... Wystarczy zwykły JavaScript. –

+8

OP pisze wtyczkę jQuery sp wydaje się głupie, aby dać bardziej skomplikowane rozwiązanie, gdy byłoby najbardziej sensowne użycie funkcji jQuery wewnątrz wtyczki jQuery. –

3

Nie rozumiem Twoje pytanie bardzo dobrze, ale myślę, że należy użyć $ .extend funkcję:

Settings=$.extend(Settings, Type.video); 

w ten sposób ustawienia dostanie Type.video właściwości

+0

Wystarczająco fair w kwestii. Dzięki za przykład, to jest idealne. –

6

Jeśli jesteś za pomocą jQuery powinieneś sprawdzić funkcję $.extend.

Można spróbować czegoś takiego:

$.fn.somePlugin = function(options){ 
    settings = $.extend(true, {default_values: "foo"}, options); 
} 
12

Non-jQuery rozwiązanie jest:

YOUROBJ.vars = { 
    vars1: { 
     vars1_1: 'an object which will overwrite', 
     vars1_2: 'an object which will be added' 
    } 
}; 

YOUROBJ.vars2 = (!YOUROBJ.vars) ? {} : YOUROBJ.vars; 

YOUROBJ.vars = { 
    vars1: { 
     vars1_1: 'an object which will be overwritten', 
     vars1_3: 'an object which will remain' 
    } 
}; 

YOUROBJ.extend = function(obj, defaults) { 
    for (var i in defaults) { 
     if (!obj[i]) { 
      obj[i] = defaults[i]; 
     } else { 
      YOUROBJ.extend(obj[i], defaults[i]); 
     } 
    } 
}; 
YOUROBJ.extend(YOUROBJ.vars, YOUROBJ.vars2); 
delete YOUROBJ.vars2; 

Funkcja ta jest przydatna, jeśli chcesz dodać zmienną do ogólnych funkcji obiektu przed jej został załadowany i utworzony.

Umożliwia to również działanie drugiego ustawienia YOUROBJ.vars jako ustawienia domyślnego.

+0

Hej, dzięki! To jest bardzo przydatne. –

+4

Co oznacza "FC"? – mediafreakch

+0

Domyślam się, że używają tego kodu w bazie kodu, nazywając go 'FC', i zmienili go na' YOUROBJ', aby odpowiedzieć na pytanie i po prostu spudłował. –

4

Mam też stworzyliśmy funkcję "scalić" w javascript, aby korzystać z moich ogólnych celów:

if (typeof Object.merge !== 'function') { 
    Object.merge = function (o1, o2) { // Function to merge all of the properties from one object into another 
     for(var i in o2) { o1[i] = o2[i]; } 
     return o1; 
    }; 
} 

Zastosowanie:

var eDiv = document.createElement("div"); 
var eHeader = Object.merge(eDiv.cloneNode(false), {className: "header", onclick: function(){ alert("Click!"); }}); 

To szybsza i brudniejsze (płytkie kopia), ale robi czego potrzebuję.

+0

Ostrzeżenie: rozszerzenie prototypu obiektu w ten sposób jest niewskazane i generalnie niebezpieczne. Całkiem dobrze napisać o niebezpieczeństwach tego i kiedy/jak można uciec z tego tutaj http://sugarjs.com/natywny i świetny wykład na ten temat tutaj http://blip.tv/jsconf/jsconf2011- andrew-dupont-wszystko-jest dozwolone-rozszerzenie-wbudowane-5211542 – timoxley

+3

@timoxley: Jeśli przyjrzysz się uważnie, to w rzeczywistości nie modyfikuje prototypu obiektu. – palswim

+1

masz rację. Biorę to wszystko z powrotem D: – timoxley

1

prostu pierwszy poziom łączących (dodanie kluczy drugiego przedmiotu do pierwszej)

var mergeObjects = function (originalObject, objectToAppend) { 
    for (var item in objectToAppend) { 
     if (objectToAppend.hasOwnProperty(item)) { 
      originalObject[item] = objectToAppend[item]; 
     } 
    } 
}; 

originalObject musi niezerowe!

+0

W jakim przypadku hasOwnProperty wywoła fałszywy wynik kontroli? Czy istnieją dodatkowe elementy, które pętla foreach wyodrębni z obiektu? – Prusprus

+1

@Prusprus * ["Używanie hasOwnProperty() zapobiega wyliczaniu pętli przez dowolne odziedziczone właściwości obiektu"] (http://brianflove.com/2013/09/05/javascripts-hasownproperty-method/) * – user11153

+0

To dobre odniesienie, dzięki za to. Sądzę więc, że jestem nieco zdezorientowany, w jaki sposób tablica (powiedzmy w przykładzie podanym przez adres URL) może mieć odziedziczone właściwości, jeśli jest to tylko tablica? – Prusprus

13

JavaScript ma prostą natywną funkcję do scalania obiektu. która jest Object.assign() wprowadzona w ES6.

// creating two JavaScript objects 
    var x = { a: true };var y = { b: false}; // merging two objects with JavaScript native function 
    var obj = Object.assign(x,y); 
    //result 
    Console.log(obj); // output is { a: true, b: false } 

Więcej informacji na temat łączenia javascript obiektu należy sprawdzić w merge JavaScript objects z przykładów.

+0

Rewizja. Musiałem uaktualnić węzeł, ponieważ błąd "niezdefiniowany nie jest funkcją" - nawet gdy działa węzeł z flagą --harmony ... –

+0

To nie działa z warstwami zagnieżdżonymi w obiektach, działa tylko na najwyższym poziomie – thxmike

0

Można również użyć tego wielorazowego komponentu, który jest oparty na Object.assign i łączy wiele obiektów w jeden bez mutowania oryginalnych obiektów.

Przykłady:

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

const obj = merge(o1, o2, o3); 
console.log(obj); // { a: 1, b: 2, c: 3 } 
console.log(o1); // { a: 1 } does not mutate objects 
Powiązane problemy