function().. を省く (map,filter時に便利)

function と何度も入力していると、指が function と入力するのに適した形にゆがみそうなので書いた。

  nodes.map(function(v)v.href.replace(/.*\//,''))

  nodes.map(V.href().replace(/.*\//,''))

とかけるようにする魔法のオブジェクト。
http://d.hatena.ne.jp/javascripter/20081002/1222940338
をヒントに、さらに変態っぽくしてみた物。

(function () {

  let V = (function () { // {{{
    const pests = [
      '__defineGetter__', '__defineSetter__', 'hasOwnProperty', 'isPrototypeOf',
      '__lookupGetter__', '__lookupSetter__', '__parent__', 'propertyIsEnumerable',
      '__proto__', 'toSource', 'toString', 'toLocaleString', 'unwatch', 'valueOf', 'watch'
    ];

    function id (value)
      value;

    function memfn (parent)
      function (name, args)
        FFF(function (self)
              let (s = parent(self))
                let (f = s[name])
                  (f instanceof Function ? s[name].apply(s, args) : f));

    function mem (parent)
      function (name)
        FFF(function (self)
              parent(self)[name]);

    function FFF (parent) {
      parent.__noSuchMethod__ = memfn(parent)
      parent.m = {__noSuchMethod__: mem(parent)};
      pests.forEach(function (it) (parent[it] = function () parent.__noSuchMethod__(it, arguments)));
      return parent;
    };

    return FFF(id);
  })(); // }}}

  // Test
  if (1) { // {{{

    // for Vimperator
    function log (msg)
      liberator.log(msg);

    function assertEqual (name, except, func) {
      let result = func();
      log((except === result) ? ("OK: " + name + ":")
                              : ("Fail: " + name + ": except = " + except + ", but was " + result));
    }

    function assertError (name, func) {
      try {
        func();
        log('Fail: ' + name + ': no error');
      } catch (e) {
        log('OK: ' + name + ': ' + e);
      }
    }

    // 普通にテスト
    assertEqual(
      'std',
      '4',
      function ()
        let (f = V.replace(1, 6).match(/\d+/).index().toString())
          f('maoa616')
    );

    // toString
    assertEqual(
      'toString',
      'string',
      function ()
        let (f = V.toString())
          (typeof f(111))
    );

    // toString
    assertEqual(
      'map.toString',
      'string',
      function ()
        let (f = V.toString())
          (typeof [1].map(f, 1)[0])
    );

    // length, arity, name などはうまくいかない。
    // Function の読み取り専用(__defineGetter__) なプロパティなので。
    assertError(
      'length',
      function ()
        let (f = V.replace(1, 6).length())
          f('damn')
    )

    // 上のような(length,arity,name)プロパティは .m でとれる。
    assertEqual(
      '.m.length',
      4,
      function ()
        let (f = V.replace(1, 6).m.length())
          f('good')
    )

    // プロパティが関数じゃないときは自動的にプロパティの値を返す関数になる
    assertEqual(
      'prop',
      'meow',
      function ()
        let (f = V.neko())
          f({neko: 'meow'})
    )

    // オブジェクトのメソッドを値として得たい場合は .m を使う
    assertEqual(
      'prop-func',
      window.alert,
      function ()
        let (f = V.m.neko())
          f({neko: window.alert})
    )

    // V のみの時は id 関数になる
    assertEqual(
      'id',
      "neko",
      function ()
        let (f = V)
          f("neko")
    )

  } // }}}

})();

冒頭の例が間違っていたので修正 11/17 09:45

s/V.href/V.href()/