2014-10-01 77 views
1

所以我使用$ .extend来组合多个组件(对象)。其中一些组件具有使用相同密钥的功能。我希望最终的扩展对象具有相同的键,但是它指向一个函数,它依次调用所有合并的组件版本。jQuery使用相同的函数扩展多个对象

所以它会是这个样子:

var a = { foo: function() { console.log("a"); } }; 
var b = { foo: function() { console.log("b"); } }; 
var c = {}; // Doesn't have foo 

var d = $.extend({}, a, b, c); 
var e = $.extend({}, a, c); 
var f = $.extend({}, c); 

d.foo(); // Should call function() { console.log("a"); console.log("b"); } 
e.foo(); // Should call function() { console.log("a"); } 
f.foo(); // Should call function() {} 

是否有这样做的一个务实的方式?我只想对特定的一组键进行此操作,因此我只想将这些特定键的功能合并在一起,并让顺序覆盖其他任何内容。

希望这是有道理的:S

回答

1

f.foo(); // Should call function() {} 

对象c没有出现拥有财产性foo。调用f.foo()返回TypeError: undefined is not a function。不确定是否需要将foo函数添加到扩展的f对象,或从匿名函数返回对象c(空对象)?在下面的片段中,foo函数不是添加到扩展的f对象。

jQuery的$.Callbacks()用来在$.each()

添加有foo属性函数尝试

var a = { foo: function() { console.log("a"); } }; 
var b = { foo: function() { console.log("b"); } }; 
var c = {}; // Doesn't have foo 

//d.foo(); 
// Should call function() { console.log("a"); console.log("b"); } 
//e.foo(); 
// Should call function() { console.log("a"); } 
//f.foo(); 
// Should call function() {} 

var callbacks = $.Callbacks(); 
var arr = [], d, e, f; 
$.each([a,b,c], function(k, v, j) { 
    var j = [a,b,c]; 
    // filter objects having `foo` property 
    if (v.hasOwnProperty("foo")) { 
    arr.push([v, v.foo]); 
    if (arr.length > 1) { 
     callbacks.add(arr[0][1], arr[1][1]); 
     // `add` `foo` properties to `callbacks` 
     // `fire` both `callbacks` when `object.foo` called 
     j[k -1].foo = callbacks.fire; 
     d = $.extend({}, j[k - 1]) 
    } else { 
     // `else` extend original data (`fn`, `object`) 
     // contained within object 
     e = $.extend({}, j[k + 1]); 
     f = $.extend({}, j[++k + 1]); 
    } 
    } 
}); 

d.foo(); // `a` , `b` 
e.foo(); // `b` 
console.log(f); // `Object {}` 
f.foo() // `TypeError: undefined is not a function` 

的jsfiddle http://jsfiddle.net/guest271314/3k35buc1/

jQuery.Callbacks()

+0

谢谢!我希望能够在返回的对象上调用foo,而不管组件是否包含它。我将不得不更深入地了解你的答案,但似乎我可以使用你的解决方案,但只是在虚拟函数foo中不存在的情况下添加虚拟函数f – Andrew 2014-10-03 19:24:47

+0

欢迎您:)是的。谢谢 – guest271314 2014-10-04 15:36:38

0

这里是我结束了基于关闭guest271314的回答。 toMix是要混合到对象中的组件数组。我其实并不需要我认为可能的虚拟函数,而最终我使用了一组函数而不是$ .Callbacks(),以便可以控制函数的调用顺序。我还需要使用call()函数,以便我可以从正确的this对象中调用函数。

this.functionMerge = function(toMix) { 
    var callbacks = {}; 
    var functions = {}; 
    var obj = {}; 
    var keys = [ 
    'componentWillMount', 
    'componentDidMount', 
    'componentWillUpdate', 
    'componentDidUpdate', 
    'componentWillUnmount' 
    ] 

    $.each(keys, function(key, value) { 
    callbacks[value] = []; 
    }); 

    for (i = 0; i < toMix.length; ++i) { 
    $.each(keys, function(key, value) { 
     if (toMix[i].hasOwnProperty(value) && typeof toMix[i][value] == 'function') { 
     callbacks[value].push(toMix[i][value]); 
     } 
    }); 
    $.extend(true, obj, toMix[i]); 
    } 

    $.each(keys, function(key, value) { 
    functions[value] = function() { 
     var that = this; 
     $.each(callbacks[value], function(key, value) { 
     value.call(that); 
     }); 
    }; 
    }); 

    return $.extend(true, obj, functions); 
}