尽管在 Javascript 中不可能知道一个函数将在另一个函数之后被调用,但这里有一个链接对象的解决方案:
(function(window, undefined)
{
var chainify = function(prop)
{
return new chainify.init(prop);
};
/**
*
* @param prop :
* Properties to apply to the object
* @returns {chainify.init}
*/
chainify.init = function(prop)
{
for ( var key in prop)
this[key] = prop[key];
};
chainify.init.prototype = {
_attributes : {},
_chain_in_progress : false,
_chain_level : 1,
_chain_function : '',
/**
* Returns the chained object
*
* @param name -
* name of the previous function
* @this chainify.init
* @returns {chainify.init}
*/
_chain : function(name)
{
var tmp = chainify(this);
tmp._chain_in_progress = true;
tmp._chain_function = name || '';
_chain_level++;
return tmp;
},
get : function(key)
{
return this._attributes[key];
},
set : function(key, value)
{
this._attributes[key] = value;
return this;
},
attr : function(prop)
{
for ( var key in prop)
this._attributes[key] = prop[key];
return this;
},
};
// Make global
window.chainify = chainify;
})(window);
var myObject = window.chainify({
// f1() function is using _chain()
f1 : function(s)
{
// Do something
this.set('s1', s);
if (this._chain_in_progress) alert('f1 after ' + this._chain_function);
// return the chain by calling this._chain()
return this._chain('f1');
},
// f2() function is using _chain()
f2 : function(s)
{
this.set('s2', s);
if (this._chain_in_progress) alert('f2 after ' + this._chain_function);
return this._chain('f1');
},
// that() function is not using _chain(), but we return this so the chaining
// is not broken
that : function(s)
{
// Do something
return this;
}
});
// Check if the f1 function is working
myObject.f1('a'); // Set s1 to "a"
alert(myObject.get('s1')); // should be "a"
// check if the f2 chaining is working
myObject.f1('b').f1('c'); // f1 after f1
alert(myObject.get('s1')); // should be "c" -> changed on last f1 function
// Check if the f2 function is working
myObject.f2('a');
alert(myObject.get('s2')); // should be "a"
// check if the f2 and f1 chaining is working
myObject.f2('b').f1('c').f1('d').f2('e'); // f1 after f2, f1 after f1 ...
alert(myObject.get('s1')); // should be "d" -> changed on last f1 function
alert(myObject.get('s2')); // should be "e" -> changed last f2 function
// check the chain with that() -
myObject.that('b').f1('a').f1('z'); // f1 chained after f1
alert(myObject.get('s1')); // should be "z" -> changed on last f1 function