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
Recursive/deep extend/assign in Underscore.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 配置文档,则此功能特别有用。它允许您使用最常见的设置创建默认配置文档,然后针对特定情况覆盖这些设置。它接受任意数量的对象作为参数,让您可以对配置文档层次结构进行细粒度控制。

