汎用メソッドの簡易記法の擬似対応

  • いろいろ参考にしつつ自分で書いてみる
  • 関数のlengthを本物と同じにする(例えばArray.forEach.length == 2)

コード

(function(){
  var objects = {
    String: [
      "charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf",
      "localeCompare", "match" /*, "quote"*/, "replace", "search",
      "slice", "split", "substr", "substring", "toLocaleLowerCase",
      "toLocaleUpperCase", "toLowerCase", "toUpperCase" //, ...
    ],
    Array: [
      "pop", "push", "reverse", "shift", "sort",
      "splice", "unshift", "concat", "join", "slice",
      "indexOf", "lastIndexOf", "filter", "forEach", "every", "map", "some"
      //, "reduce", "reduceRight" //, ...
    ]
    //, ... 
  };
  var global = this;
  for (var name in objects) if (objects.hasOwnProperty(name)) {
    var methods = objects[name];
    for (var i = 0, len = methods.length, m, o; i < len; i++) {
      m = methods[i];
      o = global[name];
      if (!(m in o.prototype) || m in o) continue;

      //Array.forEach = function($,$){
      //return Function.prototype.call.apply(Array.prototype.forEach, arguments);
      //}
      o[m] = new Function(
        new Array(o.prototype[m].length + 2).join("$,").slice(0, -1),
        "return Function.prototype.call.apply(" +
          name + ".prototype." + m + ", arguments);"
      );
    }
  }
})();

問題

  • 関数を呼び出すと合計3回関数が呼ばれる (擬似メソッド→apply()→call())
    • Function.prototype.call.apply(functionObject, arguments)functionObject.apply(arguments[0], Array.prototype.slice.call(arguments, 1))、どちらが良い?

メモ

  • (仕様による言及があるので)重複する引数名を持つ関数を定義しても一応良いらしい
    • 2 つ以上の仮引数が同じ名前のために同じプロパティを共有する場合、該当するプロパティは、後出のパラメータに供給された値を与えられる
  • 本物の場合、toString()などは汎用メソッドのものにはなっていない
    • 例えばArray.toString([1,2,3])としても"1,2,3"とはならない