2009-08-26 5 views
44

У меня есть функция под названием «Colorbox» (JQuery плагин), который принимает ряд параметров, например так:Комбинирование объектов JavaScript в один

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

У меня есть несколько различных типов «это», хотя, каждый из которых их собственными свойствами. Как так:

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

Помимо этого, у меня есть другие модели поведения, логику и группу «по умолчанию» параметров (которые переписываются более специфические). То, что я пытаюсь сделать, это нажать все соответствующие параметры, из нескольких объектов, в единый объект, так что я могу просто позвонить:

$(this).colorbox(Settings); 

Как бы я перевести неизвестную группу свойств и их значений (например, «ширина» и «высота») от чего-то типа Type.video в настройках? Цель состоит в том, чтобы иметь возможность вызвать Settings.height и вернуть значение, которое я вложил.

+1

возможно дубликат [Как я могу объединить два свойства объектов JavaScript динамически] (http://stackoverflow.com/questions/171251/how-can-i-merge-properties -of-two-javascript-objects-dynamic) – givanse

+0

См. мой ответ в http://stackoverflow.com/a/33572520/2934015 для предостережений и альтернативного решения. –

ответ

82

Посмотрите на метод JQuery extend. Он может объединить два объекта вместе и все их свойства.

Из примера страницы JQuery в:

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

Теперь настройки содержит объединенные параметры и варианты объектов.

+0

Это выглядит отлично! Думаю, я думал, что для этого будет встроенный javascript-метод, но Extend, похоже, делает именно то, что мне нужно. Благодаря! –

+0

Это кажется полезным для ОП, но технически это не то, о чем спрашивает вопрос. OP не упомянул, что он хотел использовать jQuery для этого ... Просто обычный JavaScript. –

+8

OP пишет плагин jQuery sp, казалось бы, глупо дать более сложное решение, когда было бы разумно использовать функцию jQuery внутри плагина jQuery. –

3

Я не понимаю ваш вопрос очень хорошо, но я думаю, вы должны использовать функцию $ .extend:

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

таким образом настройки получите Type.video свойства

+0

достаточно справедливый вопрос. Спасибо за пример, это прекрасно. –

6

Если вы используя jQuery, вы должны проверить функцию $.extend.

Вы могли бы попробовать что-то вроде этого:

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

Не-JQuery решение является:

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; 

Это полезно, если вы хотите, чтобы добавить переменную в общих функций объекта, прежде чем он имеет был загружен и создан.

Это также позволяет второму YOUROBJ.vars действовать как настройка по умолчанию.

+0

Эй, спасибо! Это очень полезно. –

+4

Что означает «FC»? – mediafreakch

+0

Я предполагаю, что они действительно используют этот код в своей базе кода, называя его 'FC', и изменили его на' YOUROBJ', чтобы ответить на вопрос и просто пропустили место. –

4

Я также создал «сливаться» функцию в JavaScript, чтобы использовать для моих общих целей:

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

Использование:

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

Это быстрее и грязнее (мелкая копия), но это делает что мне нужно.

+0

Предупреждение: расширение прототипа объекта, как будто это нецелесообразно и вообще опасно. Довольно хорошая запись об опасностях этого и когда/как вы можете уйти отсюда здесь http://sugarjs.com/native и отличный разговор по этому вопросу здесь http://blip.tv/jsconf/jsconf2011- andrew-dupont-all-is-allowed-extend-built-ins-5211542 – timoxley

+3

@timoxley: Если вы посмотрите внимательно, это фактически не модифицирует прототип объекта. – palswim

+1

Вы правы. Я беру все это обратно D: – timoxley

1

Просто первое сращивание уровня (добавление ключей от второго объекта к первому):

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

originalObject должен быть ненулевым!

+0

В каком случае hasOwnProperty запускает ложный результат в проверке? Есть ли дополнительные элементы, которые цикл foreach извлекает из объекта? – Prusprus

+1

@Prusprus * ["Использование hasOwnProperty() предотвращает перечисление цикла по любым унаследованным свойствам объекта"] (http://brianflove.com/2013/09/05/javascripts-hasownproperty-method/) * – user11153

+0

Это хорошая рекомендация, спасибо за это. Поэтому я думаю, что я немного смущен тем, как массив (скажем, в примере, указанном через ваш URL-адрес) может иметь унаследованные свойства, если это всего лишь массив? – Prusprus

13

У JavaScript есть простая нативная функция для слияния объекта. который является Object.assign(), введенным в 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 } 

для получения дополнительной информации о яваскрипте слияния объекта, пожалуйста, проверьте на merge JavaScript objects с примерами.

+0

Upvoted. Мне пришлось обновить узел из-за ошибки «undefined is not a function» - даже при запуске узла с флагом --harmony ... –

+0

Это не работает с вложенными слоями в объектах, оно работает только на верхнем уровне – thxmike

0

Этот компонент object-merge можно использовать повторно, который полагается на Object.assign и объединяет несколько объектов в один, не изменяя исходные объекты.

Примеры:

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 
Смежные вопросы