Для копирования объектов и их объединения можно использовать средства Yahoo UI 2:
Поэтому пришлось написать подобные функции самому (copyObj имеет дополнительный функционал, копируя массивы не как объекты, а как массивы, а также не копируя функции, оставляя их как есть):
YAHOO.lang.augmentObject({},obj)Проблема этих методов в том, что они не выполняют рекурсивное копирование полей объектов в случае, если они сами являются объектами. Проверяется это просто:
YAHOO.lang.merge(obj1, obj2)
var a = {a:{a:"a",b:"b"}}В принципе, можно было и не проверять, я просто посмотреть в исходниках, где явно видно, что поля переносятся простым присваиванием (http://developer.yahoo.com/yui/docs/Lang.js.html). Т.к. из тех же исходников видно, что метод merge вызывается augmentObject, и, следовательно, при его использовании полученный объект также будет ссылаться своими полями на теже объекты, что и поля исходных объектов.
alert(a.a.a);// выведет "а"
var b = YAHOO.lang.augmentObject({},a);
alert(b.a.a);// выведет "а"
a.a.a = "b"alert(a.a.a);// выведет "b", что естественноalert(b.a.a);// выведет "b", что говорит о том, что поле b.a ссылается реально на тот же объект, что и a.a
Поэтому пришлось написать подобные функции самому (copyObj имеет дополнительный функционал, копируя массивы не как объекты, а как массивы, а также не копируя функции, оставляя их как есть):
/**
* Копирует объект (рекурсивно)
* Аналогична YAHOO.lang.augmentObject({},obj), только выполняет копирование полей
* рекурсивно, т.е. если поле - объект, то он тоже копируется.
*/
function copyObj(obj)
{
// если передан не объект - копировать не надо, возвращаем значение. Функции тоже не копируем
if(!(obj instanceof Object) || obj instanceof Function)
return obj;
// иначе - производим рекурсивное копирование всех полей (в т.ч. унаследованных). Объекты возвращаем
// как объекты, массивы - как массивы
var ret;
if(obj instanceof Array)
ret = new Array();
else
ret = Object();
for(var key in obj)
ret[key] = copyObj(obj[key]);
return ret;
}
/**
* Объединяет объекты, возвращая новый объект
* (все поля нового объекта являются копиями (рекурсивными, т.е. полнями)
* переданных объектов, т.е. изменение переданных объектов никак не повлияет
* на результат, полученный с помощью данной функции)
* Аналогична YAHOO.lang.merge, только копирование полей из переданных объектов выполняется
* рекурсивно (т.е. если поля переданных в качестве аргументов объектов сами являются объектами,
* они копируются в выходной объект не присваиванием, а вызовом copyObj, которая рекурсивно копирует
* поле в новый объект)
* TODO: распространить на любое число объектов-аргументов
*/
function mergeObjects(obj1, obj2)
{
var ret = copyObj(obj1);
for(var key in obj2)
ret[key] = copyObj(obj2[key]);
return ret;
}
Комментариев нет:
Отправить комментарий