Подтвердить что ты не робот

Рекурсивная/глубокая протяжка/назначение в 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'
    }
}
4b9b3361

Ответ 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 для этого.