В javascript объекты передаются и копируются по ссылке. Рассмотрим пример:
var obj = { number: 1 };
// Копируем объект
var copy = obj;
copy.number = 777;
alert(obj.number);
В результате выполнения данного кода на экран будет выведено число 777 (а не 1 как ожидалось). Переменные obj и copy - одна и та же ссылка.
Как передать объект по значению? Нам нужна функция clone.
Я пробовал множество функций, но в них было много недостатков (не копировались методы объекта, или массивы). В итоге нашлась хорошая реализация (из фреймворка ExtJS). Я немного подправил эту функцию, вот результат:
if(!o || ‘object’ !== typeof o) {
return o;
}
varc = ‘function’ === typeof o.pop ? [] : {};
var p, v;
for(p in o) {
if(o.hasOwnProperty(p)) {
v = o[p];
if(v && ‘object’ === typeof v) {
c[p] = clone(v);
}
else {
c[p] = v;
}
}
}
return c;
}
Проверяем действие функции:
var c = clone(o); // делаем клон объекта
c.arr[0] = 77;
c.arr[1] = 88;
c.arr[2] = 99;
// Значения остались прежними
alert(o.arr[0]); // 1
alert(o.arr[1]); // 2
alert(o.arr[2]); // 3
// Методы тоже были скопированы
c.get(); // 88
o.get(); // 2
Как видно из примера, функция clone скопировала объект o вместе со всеми его свойствами и методами.
Пользуйтесь на здоровье :)
Июнь 6th, 2008 at 7:52 пп
Согласен. Так удобнее.
Июнь 27th, 2008 at 9:50 дп
gde to ja yze eto chital.
Июнь 27th, 2008 at 10:02 дп
@ evol1980:
Мой блог - это, в первую очередь ресурс для меня, и размещать чужие статьи здесь я не собираюсь.
Июль 16th, 2008 at 10:30 дп
Я вам очень благодарен, мне понравилось.
Июль 19th, 2008 at 12:51 пп
oj sorri oshibsa
Август 6th, 2008 at 12:39 пп
opat vernylsa na etot sajt ctob skazat spasibo :)
Сентябрь 30th, 2008 at 9:26 пп
На самом деле, ситуаций, когда нужна одна лишь функция «clone(…)», практически не бывает. В реальных проектах обычно есть функция «extent», а на её основе строят функцию «clone».
function extend(obj, hash) {
for(var key in hash)
if(hash.hasOwnProperty(key))
obj[key] = hash[key];
}
function clone(obj) {
return extend({}, obj);
}
То есть для копирование объекта, создаётся новый объект и расширяется методами и атрибутами переданного.
Декабрь 18th, 2008 at 11:22 пп
Хорошая статья. Спасибо =)
2Octane: а функция extend не должна возвращать объект??
return obj;
Январь 5th, 2009 at 3:01 пп
не должна - объекты передаются по ссылки.
Январь 23rd, 2009 at 11:53 дп
[…] повторное использование кода - это хорошо, я выгуглил кое-что существующее. Однако, меня не устроило то, что эта реализация не […]
Январь 23rd, 2009 at 11:59 дп
Tnanx! Немножко модифицировал.
http://shcoder.ru/2009/01/23/javascript-utils-clone/
Март 17th, 2009 at 3:25 дп
Хм… читаю блоги по близкой тематике, а к Вам ни разу не наведывалась, добавила в избранное, я теперь Ваш постоянный читатель :)
Август 22nd, 2009 at 4:49 пп
Не понял как сделать, что бы работало 2 копии одного объекта но с разными свойствами?
У меня работал объект, который подгружал контент в div, теперь пытаюсь использовать этот же класс, что бы подгрузить во второй div.
Пишу:
engine.init(null, $(”#d1″), 0 );
var engine2 = engine;
engine2.init(null, $(”#d2″), 1);
А контент выводит во втором div, который должен быть в первом, а в первом вообще пусто.
Апрель 28th, 2010 at 1:11 пп
Встретил в гугловском коде похожую функцию (obj target object, vals source object):
var setVals = function (obj, vals) {
if (obj && vals) {
for (var x in vals) {
if (vals.hasOwnProperty(x)) {
if (obj[x] && typeof vals[x] === ‘object’) {
obj[x] = setVals(obj[x], vals[x]);
} else {
obj[x] = vals[x];
}
}
}
}
return obj;
};
Май 4th, 2010 at 10:17 дп
спасибо за пример функции для клонирования, есть небольшое добавление:
функция клонирует только свойства и методы объекта, но оставляет неизменным его прототип.
можно заменить:
var c = ‘function’ === typeof o.pop ? [] : {};
на:
var c = []
if (o.constructor !== Array) {
function P () {}
P.prototype = o.constructor.prototype;
c = new P();
}