便利なコールバック

毎回手を書くのにうんざり。 引数の配列を持つ関数と、これに依存しないfireメソッドを持つオブジェクトのコンテキストを理解する簡単なスクリプトを書いたので、「クリーン」コードだけでなく、onclickまたはタイマーにもコールバックをフックできます。 実行可能関数のセットと、それぞれの引数/コンテキストは任意です。



ジンジャーブレッドクッキーのうち、エラーの発生を粉砕し、コルベックの開始回数を制限し、他のジンジャーブレッドを好みに合わせて焼くことができるようにするだけです。



スクリプト自体

function _callback(fn, args, ctx, decorators) {

// -

// fn - ():

// , {fn: function, args: [], ctx: {}},

// ,

// args -

// ctx - (this)

// decorators - ,

//

var ret = new _callback.Def(fn, args, ctx);

if (decorators) {

var d = _callback.decorators;

for ( var key in decorators) {

if (key in d) ret = new d[key](ret, fn, args, ctx, decorators[key]);

}

}

return ret;

}

_callback.Def = function (fn, args, ctx) {

var dublicate = this ; // myClb.fire dom-,

//

var arrayOrNull = function (ar) { return ar && ar.constructor == Array ? ar : null ; };



setFn(fn);



this .updateFn = updateFn;

//this.__defineSetter__("fn", setFn); // ie

//this.__defineGetter__("fn", function() { return fn; });



function fireByFn(myArgs, myFn, myCtx) {

// -

(myFn || fn).apply(myCtx || ctx || null , arrayOrNull(myArgs) || arrayOrNull(args) || []);

return dublicate;

}

function fireByArray(myArgs, myFn, myCtx) {

// ,

for ( var i=0, ar=myFn||fn, c=myCtx||ctx, a=arrayOrNull(myArgs) || arrayOrNull(args), l=ar.length; i<l; i++) getFireFn(ar[i])(a, ar[i], c);

return dublicate;

}

function fireByJSON(myArgs, myJson, myCtx) {

// JSON

var json = myJson || fn;

getFireFn(json.fn)(arrayOrNull(json.args) || arrayOrNull(myArgs), json.fn, json.ctx || myCtx);

return dublicate;

}



function getFireFn(fn) {

//

var type = dublicate._getTypeofFireFn(fn), fireFn;

switch (type) {

case "json" : return fireByJSON; break ;

case "array" : return fireByArray; break ;

case "function" : return fireByFn; break ;

}

return fireFn;

}



function setFn(val) {

// fire

dublicate.fire = getFireFn(fn = val);

}

function updateFn(transformFn) {

setFn(transformFn(fn));

return dublicate;

}

};

_callback.Def.prototype._err = function () { this ._err.withoutFn(); };

_callback.Def.prototype._err.withoutFn = function () {

throw "_callback: wrong fn argument" ;

};

_callback.Def.prototype._getTypeofFireFn = function (fn) {

// : , ,

if (!fn) this ._err.withoutFn();

if ( typeof fn == "function" ) return "function" ;

if (fn.constructor == Array) {

for ( var i=fn.length; i--;) this ._getTypeofFireFn(fn[i]);

return "array" ;

} else {

// {}

this ._getTypeofFireFn(fn.fn);

return "json" ;

}

this ._err.withoutFn();

};

_callback.decorators = {};

_callback.decorators._copy = function (component, orig, instance) {

for ( var key in component) orig[key] = instance[key] = component[key];

//instance.__defineSetter__("fn", function(val) { component.fn = val; }); // ie

//instance.__defineGetter__("fn", function() { return component.fn; });

};

_callback.decorators.count = function (component, fn, args, ctx, misc) {

var orig = {};

_callback.decorators._copy(component, orig, this );

var fired = misc;



this .fire = fire;



function fire() {

if (!fired) return ;

fired--;

component.fire();

}

};

_callback.decorators.stopThrow = function (component, fn, args, ctx, misc) {

var orig = {};

_callback.decorators._copy(component, orig, this );

this .fire = fire;



function fire() {

try {

component.fire();

} catch (er) {}

}

};

_clb = _callback;




* This source code was highlighted with Source Code Highlighter .








使用例

.fireで応答する関数を準備します
var res = "" ;

addLine = function (str) {

res += str + "\n" ;

};



function f1(q, w, e) {

addLine( "f1: " + q + ", " + w + ", " + e + "; this.q = " + this .q);

}

function f2(q, w, e) {

addLine( "f2: " + q + ", " + w + ", " + e + "; this.q = " + this .q);

}

function f3(q, w, e) {

addLine( "f3: " + q + ", " + w + ", " + e + "; this.q = " + this .q);

}

function f4(q, w, e) {

addLine( "f4: " + q + ", " + w + ", " + e + "; this.q = " + this .q);

}

function f5() {

uNdEfInEd++;

addLine( "f5" );

}




* This source code was highlighted with Source Code Highlighter .








そして、実際には、使用例
// :

q = _clb(

f1, // , ...

[1,2,3], // ... ...

{q:5} // ... (this.q==5)

);

q.fire(); //

// f1: 1, 2, 3; this.q = 5

q.fire([8]); //

// f1: 8, undefined, undefined; this.q = 5

q.fire( false , false , {q:11}); // , this

// f1: 1, 2, 3; this.q = 11

q.fire([]); //

// f1: undefined, undefined, undefined; this.q = 5

addLine( "----" ); //

//

q = _clb([f1, f2, f3], [1,2,3], {q:5}); // ,

q.fire();

// f1: 1, 2, 3; this.q = 5

// f2: 1, 2, 3; this.q = 5

// f3: 1, 2, 3; this.q = 5

q.fire([8]); // ""

// f1: 8, undefined, undefined; this.q = 5

// f2: 8, undefined, undefined; this.q = 5

// f3: 8, undefined, undefined; this.q = 5

addLine( "----" );



// JSON :

q = _clb(

[

f1, // f1: 1, 2, 3; this.q = 5

{fn: f2, args: [4, 5, 6]}, // f2: 4, 5, 6; this.q = 5

{

fn: [

f2, // f2: 7, 8, 9; this.q = 0

{fn: f2, args: [4, 5, 6]}, // f2: 4, 5, 6; this.q = 0

f3 // f3: 7, 8, 9; this.q = 0

],

args: [7, 8, 9], //

ctx: {q: 0} //

}

],

[1,2,3], //

{q:5} //

).fire();

addLine( "----" );



// :

q.updateFn( function (fn) {

// ,

fn.splice(1, 5);

fn.push(f1, f1);

return fn;

}).fire(); // : f1: 1, 2, 3; this.q = 5

addLine( "----" );



// ie, __defineSetter__ __defineGetter__ :

//q.fn = [f2, {fn: f2, args: [], ctx: {}}, {fn: f3, args: [7, 8, 9], ctx: {q: 0}}];

//q.fire();

//addLine("----");



// :

q = _clb(f5, false , false , {stopThrow: true }).fire(); //



// - :

q = _clb(f1, [1,2,3], {q:5}, {count: 1});

q.fire(); // f1: 1, 2, 3; this.q = 5

// 1 0

q.fire(); //



alert(res);




* This source code was highlighted with Source Code Highlighter .




私はとても賢く、他のオプションを知りたいと思っている唯一の人ではないと思います。



All Articles