一度しか呼ばれない函數を作る。
.。oO(二度クリックされて困る様なものは、二度クリックされない様に仕込んどきなさい。)
— みんな☆ももんが連山さっちゃん♬♪♡ (@ne_sachirou) June 26, 2013
jQuery().one()やZepto().one()とか使ふ迄も無い。
/** * @return {Function} */ Function.prototype.one = function() { return one(this); }; function one(fun) { var result, i = 1; return function() { if (i > 0) { i -= 1; result = fun.apply(this, arguments); } return result; }; }
以下に使ふ。
document.addEventListener('click', callback.one()); function callback(evt) { console.count(); return evt; }
何度呼んでも同じ値が帰って來る。副作用は一度きりだ。callback.one()
ではなく、one(callback)
形式でも好い。
UFSC
Pythonのself渡しとか、dlangのUFCS (Uniform Function Call Syntax) っぽくやってみたよ。どちらかと言うとPythonのself渡しだよ。意地だよ。要らないよ。
/** * @return {Function} */ Function.prototype.one = uniform(one); function one(fun) { var result, i = 1; return function() { if (i > 0) { i -= 1; result = fun.apply(this, arguments); } return result; }; } function uniform(fun) { return function() { return fun.apply(this, [this].concat(toArray(arguments))); } } function toArray(obj) { // return [].slice.call(obj); var arr = []; for (var i = 0, iz = obj.length; i < iz; ++i) arr.push(obj[i]); return arr; }
高機能版
- 一定時間経てば呼び出せるようにする機能。
- 何故かon/offを切り替えられる機能。
/** * @param {number=} duration milliseconds =infinity * @return {Function} */ Function.prototype.one = function(duration) { return one(this, duration); }; // Function.prototype.one = uniform(one); function one(fun, duration) { return nth(fun, 1, duration); } function nth(fun, n, duration) { var result, callback, i = n; callback = function() { if (i > 0) { i -= 1; if (i <= 0 && duration > 0) setTimeout(function() { i = n; }, duration); result = fun.apply(this, arguments); } return result; }; callback.on = function() { i = n; }; callback.off = function() { i = 0; }; callback.toggle = function() { i = (i <= 0 ? n : 0); }; return callback; } // function uniform(fun) { // return function() { // return fun.apply(this, [this].concat(toArray(arguments))); // } // } // // function toArray(obj) { // var arr = []; // for (var i = 0, iz = obj.length; i < iz; ++i) { // arr[i] = obj[i]; // } // return arr; // }
短くすると
短くすると此う成る。
function one(f){return function(){f&&f.apply(0,arguments);f=0}}
cf. [JavaScript] Javascriptで一度しか呼ばれない関数 - ごちゃまぜの音 http://jumble-note.blogspot.jp/2013/06/javascript-javascript.html
通常此う云ふものはevent listenerとして呼ばれるから、返り値は不要だ。逆に引数は重要だ。
短くして、拡張性も無くなったし、意図もよみ辛く成った。Closure Compiler等のminifier & 最適化toolを使へば好い。手で短いcodeにする価値を感じない。simpleさを犠牲にする丈だ。