Для тех, кто не использует jQuery, здесь идет решение vanilla-js.
Решение:
function extend (target) {
for(var i=1; i<arguments.length; ++i) {
var from = arguments[i];
if(typeof from !== 'object') continue;
for(var j in from) {
if(from.hasOwnProperty(j)) {
target[j] = typeof from[j]==='object'
? extend({}, target[j], from[j])
: from[j];
}
}
}
return target;
}
Сжатый (с Closure Compiler):
только 199 символов!
var extend=function e(c){for(var d=1;d<arguments.length;++d){var a=arguments[d];if("object"===typeof a)for(var b in a)a.hasOwnProperty(b)&&(c[b]="object"===typeof a[b]?e({},c[b],a[b]):a[b])}return c}
Как использовать:
extend(target, obj1, obj2); // returns target
Если вы только хотите объединить, используйте
var merged = extend({}, obj1, obj2);
Особенности:
- Он не смотрит на прототип объектов.
- Игнорирует не объекты.
- Рекурсивный, чтобы объединить свойства, являющиеся объектами.
- Объекты, на которые ссылаются объекты
target
, если они расширены, заменяются новыми, а оригинальные не изменяются.
- В случае одинаковых имен свойств объединенное значение будет состоять из объединения объектов после последнего (в порядке аргументов) значения, отличного от объекта. Или, если последний не является объектом, сам.
Примеры:
extend({}, {a:1}, {a:2}); // {a:2}
extend({}, {a:1}, {b:2}); // {a:1, b:2}
extend({}, {a: {b:1}}, {a: {b:2}}); // {a: {b:2}}
extend({}, {a: {b:1}}, {a: {c:2}}); // {a: {b:2, c:2}}
extend({}, {a: {a:1}}, {a: {b:2}}, {a: 'whatever non object'});
// {a: "whatever non object"}
extend({}, {a: {a:1}}, {a: {b:2}}, {a: 'whatever non object'}, {a: {c:3}},{a: {d:4}});
// {a: {c:3, d:4}}
Предупреждение:
Имейте в виду, что если браузер не достаточно умен, он может оказаться в ловушке в бесконечном цикле:
var obj1={},
obj2={};
obj1.me=obj1;
obj2.me=obj2;
extend({},obj1,obj2);
Если браузер достаточно умен, он может t забросить ошибку или вернуть {me: undefined}
или что угодно.
Обратите внимание, что это предупреждение также применяется, если вы используете jQuery's $.extend
.
Но это изменится «default_array» мой по умолчанию, и я не хочу, потому что это глобальная переменная ... – amp
@amp - это легко избегать использования временного объекта. – adeneo
Не могу поверить! Так очевидное решение ... – amp