Рекурсивная/глубокая протяжка/назначение в Underscore.js?
Есть ли способ получить функцию Underscore.js extend
:
Скопировать все свойства исходных объектов в объект назначения и вернуть объект назначения. Он в порядке, поэтому последний источник переопределяет свойства с тем же именем в предыдущие аргументы.
... работать рекурсивно?
Собственно, свойство query
в creditOperation
будет полностью переопределять свойство query
, определенное в baseOperation
:
var url = require('url')
, _ = require('underscore'),
, baseOperation = {
host: 'gateway.skebby.it',
pathname: 'api/send/smseasy/advanced/http.php',
protocol: 'https',
query: {
'username': 'foo',
'password': 'bar',
}
};
var creditOperation = _.extend(baseOperation, {
query: {
'method': 'baz'
}
});
console.log(url.format(creditOperation));
Я хотел бы получить этот creditOperation
:
{
host: 'gateway.skebby.it',
pathname: 'api/send/smseasy/advanced/http.php',
protocol: 'https',
query: {
'username': 'foo',
'password': 'bar',
'method': 'baz'
}
}
Ответы
Ответ 1
Нет, Подчеркивание не будет содержать глубокого расширения, поскольку оно слишком сложно для работы с различными типами объектов. Вместо этого пользователям рекомендуется внедрять свои собственные решения с поддержкой того, что им нужно.
В вашем случае это только простые объекты, поэтому реализация довольно проста:
_.deepObjectExtend = function(target, source) {
for (var prop in source)
if (prop in target)
_.deepObjectExtend(target[prop], source[prop]);
else
target[prop] = source[prop];
return target;
}
Ответ 2
С Lodash (fork подчеркивания) u может.
Метод Lodash _.extend принимает третий (или более высокий) параметр как функцию, получающую значения (старые и новые); Поэтому вы можете сделать что-то вроде этого:
var deep = function(a, b) {
return _.isObject(a) && _.isObject(b) ? _.extend(a, b, deep) : b;
};
var a = {a:{b:{c:1}}},
b = {a:{b:{z:1}}};
_.extend(a,b,deep);
обн.
Как сказал Паоло Моретти в комментариях, в lodash есть такая же функция, как _. Merge:
_.merge(a,b);
Ответ 3
jQuery имеет функцию extend(), которая делает то же самое, что и ее копия Underscore, но также имеет аргумент deep, который позволяет он сливается рекурсивно, как вам хочется:
var creditOperation = $.extend(true, baseOperation, {
query: {
'method': 'baz'
}
});
Или, если вы не хотите перезаписывать baseOperation:
var creditOperation = $.extend(true, {}, baseOperation, {
query: {
'method': 'baz'
}
});
Ответ 4
Автономная версия Bergi глубоко расширяется, включая исправление, когда значение представляет собой строку вместо объекта. Также исправлено, чтобы быть более строгим.
function deepObjectExtend (target, source) {
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
if (target[prop] && typeof source[prop] === 'object') {
deepObjectExtend(target[prop], source[prop]);
}
else {
target[prop] = source[prop];
}
}
}
return target;
}
Ответ 5
Курт Милам опубликовал смесь которая добавляет метод deepExtend
к underscore.js. Он даже имеет дело с регулярными выражениями (если хотите).
Выдержка из документации:
Смешайте его с помощью underscore.js: _.mixin({deepExtend: deepExtend});
Назовите его так: var myObj = _.deepExtend(grandparent, child, grandchild, greatgrandchild)
Примечания: Держите его сухим.
Эта функция особенно полезна, если вы работаете с конфигурационными документами JSON. Это позволяет вам создать config с наиболее распространенными настройками, затем переопределите эти настройки для конкретных случаев. Он принимает любое количество объектов как аргументы, дающие вам тонкий контроль над вашим конфигурационным документом иерархия.
Ответ 6
подчеркивание extend() не делает глубокой протяженности; по сути, нет функции в подчеркивании, которое может глубоко расширяться.
Вы можете использовать lodash merge для этого.