Javascript Underscore.js 中的递归/深度扩展/分配?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14843815/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 18:07:04  来源:igfitidea点击:

Recursive/deep extend/assign in Underscore.js?

javascriptunderscore.js

提问by gremo

Is there any way to get Underscore.js extendfunction:

有没有办法获得 Underscore.jsextend函数:

Copy all of the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments.

将源对象中的所有属性复制到目标对象,并返回目标对象。它是有序的,因此最后一个源将覆盖先前参数中的同名属性。

... to work recursively?

...递归工作?

Actually, queryproperty in creditOperationis going to completely override the queryproperty defined in baseOperation:

实际上,query属性 increditOperation将完全覆盖中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));

I'd like to obtain this creditOperation:

我想得到这个creditOperation

{
    host: 'gateway.skebby.it',
    pathname: 'api/send/smseasy/advanced/http.php',
    protocol: 'https',
    query: {
        'username': 'foo',
        'password': 'bar',
        'method': 'baz'
    }
}

采纳答案by Bergi

No, Underscore will not contain a deep extendsince it's too complicated to deal with different types of objects. Instead, users are encouraged to implement their own solutions with the support for what they need.

不,Underscore 不会包含深度扩展,因为处理不同类型的对象太复杂了。相反,鼓励用户在他们需要的支持下实施他们自己的解决方案。

In your case it's only plain objects, so an implementation is quite straightforward:

在您的情况下,它只是普通对象,因此实现非常简单:

_.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;
}

回答by Sergey Kamardin

With Lodash(fork of underscore) you can. Lodash's _.extendmethod accept third (or higher) parameter to be a function, that receives values (old and new); So you can do something like this:

使用Lodash(下划线分叉)可以。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);

upd.As Paolo Morettisaid in comments, there is the same function in lodashcalled _.merge:

更新。正如Paolo Moretti在评论中所说,lodash 中有一个相同的函数叫做_.merge

_.merge(a,b);

回答by Randy

jQuery has an extend()function, which does the same thing as its Underscore counterpart, but also has a deepargument which allows it to merge recursively as you desire:

jQuery 有一个extend()函数,它和 Underscore 对应的做同样的事情,但也有一个深度参数,允许它按照你的需要递归合并:

var creditOperation = $.extend(true, baseOperation, {
    query: {
        'method': 'baz'
    }
});

Or, if you don't want to overwrite baseOperation:

或者,如果您不想覆盖baseOperation

var creditOperation = $.extend(true, {}, baseOperation, {
    query: {
        'method': 'baz'
    }
});

回答by KrekkieD

Stand-alone version of Bergi's deep extend, including the fix for when a value is a string instead of an object. Also patched to be more strict.

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;
}

回答by peterp

Kurt Milam has published a mixin that adds a deepExtendmethod to underscore.js. It even deals with regular expressions (if you want). Excerpt from the documentation:

Kurt Milam 发布了一个mixin,deepExtend为 underscore.js添加了一个方法。它甚至处理正则表达式(如果你愿意)。文档摘录:

Mix it in with underscore.js: _.mixin({deepExtend: deepExtend});

Call it like this: var myObj = _.deepExtend(grandparent, child, grandchild, greatgrandchild)

Notes: Keep it DRY.

This function is especially useful if you're working with JSON config documents. It allows you to create a default config document with the most common settings, then override those settings for specific cases. It accepts any number of objects as arguments, giving you fine-grained control over your config document hierarchy.

将它与 underscore.js 混合: _.mixin({deepExtend: deepExtend});

像这样调用它: var myObj = _.deepExtend(grandparent, child, grandchild, greatgrandchild)

注意事项:保持干燥。

如果您正在处理 JSON 配置文档,则此功能特别有用。它允许您使用最常见的设置创建默认配置文档,然后针对特定情况覆盖这些设置。它接受任意数量的对象作为参数,让您可以对配置文档层次结构进行细粒度控制。

回答by Gaurang Patel

underscore's extend() does not do deep extend; as a matter of fact, there is no function in underscore which can deep extend.

下划线的扩展()不做深度扩展;事实上,underscore 中没有可以深度扩展的函数。

You may use lodash's mergefor that.

您可以为此使用 lodash 的合并