c4se記:さっちゃんですよ☆

.。oO(さっちゃんですよヾ(〃l _ l)ノ゙☆)

.。oO(此のblogは、主に音樂考察Programming に分類されますよ。ヾ(〃l _ l)ノ゙♬♪♡)

音樂は SoundCloud に公開中です。

考察は現在は主に Scrapbox で公表中です。

Programming は GitHub で開發中です。

JavaScriptで、一度しか呼ばれない関数を作る

一度しか呼ばれない函數を作る。



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さを犠牲にする丈だ。