jQuery.extend的反转(true,...)
我期望通过将它与一组已知的默认值进行对照来减少JSON数据的存储需求。 基本上,我想要的是jQuery的.extend()
函数的反例,以便以下测试传递给任意JSON兼容对象:
function test_delta(defaults, delta) {
var current = $.extend(true, {}, defaults, delta);
QUnit.same(get_delta(current, defaults), delta);
}
在我开始编写我自己的get_delta()
,有没有人知道现有的实现?
你真正想要的是一个对象差异(erential)算法。
不难写 -
function diff (obj1, obj2) {
var delta = {};
for (var x in obj1) {
if (obj2.hasOwnProperty(x)) {
if (typeof obj2[x] == "object") {
//recurse nested objects/arrays
delta[x] = diff(obj1[x], obj2[x]);
}
else {
//if obj2 doesn't match then - modified attribute
if (obj2[x] != obj1[x]) {
delta[x] = obj1[x];
}
}
}
else {
//obj2 doesn't have this - new attribute
delta[x] = obj1[x];
}
}
return delta;
}
alert(
JSON.stringify(
diff({ hello : 'world', gone : 'fishing' },
{ hello : 'world' })
)
);
//outputs:
{ gone : 'fishing' }
正如你所看到的,这是一个非常基本的实现 - 你可以扩展它来通过在一个单独的对象中返回obj2的添加来提供一个完整的差异。
这段代码不是没有bug的,对象原型和函数在不同浏览器中的处理方式不同,但它应该足以作为数据结构的演示。
尝试这样的事情:
jQuery.extend({
deltaExtend: function(deep, target, defaults, delta){
var result = jQuery.extend.apply(jQuery, arguments);
jQuery(result).data('delta', delta);
jQuery(result).data('defaults', defaults);
return result;
}
});
用法:
var result = $.deltaExtend(true, {}, defaults, delta);
$(result).data('delta') //returns delta object
$(result).data('defaults') //returns default object
它也可以调整,以使它适用于N个对象,只需要多一点思考。
我知道这与主题启动器有点晚了,但您可能想看看来自_.omit(object, *keys)
函数。 它就是这样。