IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

プロパティのアクセスを"呼び出せる"変なオブジェクトを作ってみた

こんなの思いつきました

function F(obj){
 var f = function(p,o){
  if(o == void(0)) return arguments.callee[p];
  return arguments.callee[p] = o;
 }
 if(obj != void(0)) for(var n in obj) f[n] = obj[n];
 return f;
}
これを使うと
var object = new F();

object.hoge = 1;
object['fuga'] = 2;
object('piyo', 3);

alert(object('hoge')); // 1
alert(object.fuga);    // 2
alert(object['piyo']); // 3

このように関数の引数という形でプロパティにアクセスできるようになる

何が便利なのか

たとえば、以下のような関数指向の関数*1がある場合に便利なのである。

Array.prototype.map = function(f) {
 var result = [];
 for (var i = 0; i < this.length; i ++) result[i] = f(this[i]);
 return result;
};

var object = new F({ hoge: 1, fuga: 2, piyo: 3}); // さっきの例と同じ値

alert(['hoge', 'piyo', 'fuga'].map(object)); // 1, 3, 2

問題点

内部プロパティ Call *2はプロトタイプによって継承することが出来ないため、このオブジェクトをプロトタイプとしてもこの特性は失われてしまう。
まあ、ライブラリを作る場合でもない限りは、プロトタイプチェーンは使わなくてもそんなに困らないので。おk

*1:prototype.js配列操作関数のような

*2:JavaScript が内部に持つ「呼び出せるオブジェクト」というしるし