Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Сравнить свойства двух объектов (https://javascript.ru/forum/misc/52029-sravnit-svojjstva-dvukh-obektov.html)

vanoha 01.12.2014 12:02

Сравнить свойства двух объектов
 
Доброго времени суток. есть два объекта, defaults и param. Первый содержит кучу свойств, второй изначально имеет только часть свойств первого. Как сделать так чтобы свойства первого, которых нет у второго присваивались второму со значениями. Пробовал такой вариант, но появляются только свойства, без значений.
for(var s in defaults){param[s]=(param[s]!='undefined')?param[s]:defaults[s];}

tsigel 01.12.2014 12:11

Проще всего через наследование. Просто кладете дефолтный объект в прототип и пихаете свои значения сверху.
Второй способ - рекурсивно.

//Тестовые данные
var defaults = {
    test1: true,
    test2: true,
    test3: {
        "test3.1": true,
        "test3.2": true
    }
};

var params = {
    test2: false,
    test3: {
        "test3.2": false
    }
};

//Сама маржилка
var result = (function (defaults, param) {

    var obj = Object.create(defaults);

    var merge = function (result, params) {
        for (var key in params) {
            if (params.hasOwnProperty(key)) {

                if (key in result && typeof params[key] == "object" && typeof result[key] == "object") {
                    merge(result[key], params[key])
                } else {
                    result[key] = params[key];
                }

            }
        }
    };

    merge(obj, params);

    return obj;

})(defaults, params);

//проверяем
alert(result.test1);
alert(result.test2);
alert(result.test3["test3.1"]);
alert(result.test3["test3.2"]);

vanoha 01.12.2014 12:20

Блин, как то мудрёно, понять не могу как работает. А можете подсказать, почему моя то не работает? Точнее на половину

ruslan_mart 01.12.2014 12:34

vanoha, потому что Вы не правильно делаете проверку на undefined, в Вашем случае Вы пытаетесь сравнить со строкой "undefined".

Проще так:
for(var s in defaults){
    param[s] = param[s] || defaults[s];
}


Ну а если именно на undefined, то:

for(var s in defaults){
    if(!(s in param)) param[s] = defaults[s];
}

tsigel 01.12.2014 12:39

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

Я поправил свой пример.

vanoha 01.12.2014 12:46

Руслан, было бы супер, если бы ваш второй вариант работал

tsigel 01.12.2014 12:46

vanoha,
В вашем варианте объект test3 перезапишется, а в моём - смержится.

vanoha 01.12.2014 12:47

tsigel, ваш скрипт ещё запутаннее для меня стал...

tsigel 01.12.2014 12:51

vanoha,
Сначала я создаю объект в прототип которого кладу ваши дефолтные данные.

Потом я перебираю объект параметров. Если элемент объект и в дефолтных данных есть объект с таким ключем - мерджим объект, в противном случае присваиваем в результат элемент из объекта параметров.

ruslan_mart 01.12.2014 12:55

vanoha, извиняюсь, s в param была лишней, поправил.

vanoha 01.12.2014 12:57

tsigel, спасибо, что то вроде начало проясняться...:)

vanoha 01.12.2014 13:00

Руслан, не ферштейн, вроде всё так и осталось, как вы писали изначально

vanoha 01.12.2014 13:02

Туплю, нашел, в переменной

vanoha 01.12.2014 13:07

Спасибо за помощь обоим. Премного благодарен.

рони 01.12.2014 14:03

Цитата:

Сообщение от vanoha
. Как сделать так чтобы свойства первого, которых нет у второго присваивались второму со значениями.

http://api.jquery.com/jQuery.extend/

krutoy 02.12.2014 11:18

vanoha,
В данном случае, использовние чего-либо помимо длегирования -- маразм
param={a: 1}
defaults=Object.create(param)
defaults.b=2
alert([defaults.a, defaults.b])

tsigel 02.12.2014 12:04

krutoy, и как это будет работать для таких объектов?
//Тестовые данные
var defaults = {
    test1: true,
    test2: true,
    test3: {
        "test3.1": true,
        "test3.2": true
    }
};

var params = {
    test2: false,
    test3: {
        "test3.2": false
    }
};

vanoha 02.12.2014 12:22

рони, используя данную функцию, как описано в статье которую вы предложили, придётся присваивать значения не от defaults param, а на оборот, а то defaults вставит все свои значения. В таком случае нужно делать копию defaults, так как дальше по скрипту он ещё нужен. Как то всё ещё мудрёнее получается...

рони 02.12.2014 12:34

vanoha,
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script>
     $(function(){
      //Тестовые данные
var defaults = {
    test1: true,
    test2: true,
    test3: {
        "test3.1": true,
        "test3.2": true
    }
};

var params = {
    test2: false,
    test3: {
        "test3.2": false
    }
};
params = $.extend(true,{}, defaults, params);
alert('params : '+JSON.stringify(params) + '\ndefaults : '+JSON.stringify(defaults))
});
  </script>

krutoy 02.12.2014 13:14

tsigel,
Странно, если у вас ничего не наследуется, зачем вам вообще что-либо копировать или делегировать. Вопрос из разряда "в огороде бузина а в киеве дядька, исходя из этого, сколько будет дважды два?"

Если Вы хотите , чтобы просто имена были частично одинаковые, создайте класс.

tsigel 02.12.2014 13:29

krutoy,
Очередной раз убедился в твоей некомпетентности.

krutoy 02.12.2014 13:34

tsigel,
А я в твоей. Но в отличии от тебя, я объяснил тебе, в чем ты зафейлился, а с твоей стороны -- это просто кукареку.

tsigel 02.12.2014 17:36

krutoy,
А я использую наследование. Если ты не заметил то я тоже кладу дефолтный объект в прототип. Просто если в объете который надо смерджить с дефолтным есть вложенные объекты, то в твоем варианте их надо либо все перебрать, либо они перезапишут то что в прототипе. В моем же варианте все смержится как надо.


Часовой пояс GMT +3, время: 16:48.