JavaScript の getter/setter について

JavaScript で getter/setter が使えるということを今更ながら知った。同じ ECMAScript ベースの ActionScript は使えるのになー、と思ってたら案の定使えた。はい。私の不勉強でした。。。

参考:

しかし、ほとんど使ってるのを見たことがない。いろんなライブラリでは速度が重視されるからか?とも思ったが、ライブラリだからこそ、こういうアクセッサメソッドは重要なんじゃないだろうか。
IEでは非サポートなので意味ないということかもしれないが。。(が、一応対応策はある)

とりあえず、どれくらい遅いのか測ってみることにした。

こんなオブジェクトを作って、直接アクセス、getter/setter アクセスの実行時間を比べてみた。

var Test = {
	a: 10,
	_num: 1,
	_str: 'hoge',
	_obj: {i: 1},
	get num() { return this._num; },
	set num(n) { this._num = n; },
	get str() { return this._str; },
	set str(s) { this._str = s; },
	get obj() {return this._obj; },
	set obj(o) { this._obj = o; },
};

なお、計測はこんな感じ。

function calcTime(count, fn){
	var d = new Date().getTime();
	for(var i=0; i<count; i++){
		fn();
	}
	var pd  = new Date().getTime();
	return (pd - d);
}

function start(){
	var aGetTime = calcTime(count, function(){
		var a = Test.a;
	});
	var aSetTime = calcTime(count, function(){
		Test.a = 100;
	});
	・・・

なぜか FireFox(3.6.13)では動かず。。。
Safari 5.0.3 と Chrome 9.0 で試しました。ループ回数は10000回で、何回か回した平均的な時間(ms)です。

項目 Safari Chrome
Test.a get 38 71
Test.a set 35 70
Test.num get 47 145
Test.num set 53 149
Test.str get 47 145
Test.str set 54 150
Test.obj.i get 47 147
Test.obj.i set 64 158

Safari はやっ!!プロパティアクセスとメソッド呼び出しはほとんど違いありません。Chromeのほうは、大体倍くらいになってますね。しかしまあ、10万回アクセスでこんなものなので通常はほとんど誤差ですね。
というわけで、積極的に使っていこうと思います。

なお、当方の環境は MacBook Air11"(OS X 10.6.6) です。

まあ、しかし毎回打つのはめんどくさいので、Objective-C の @synthesize とかみたいにできないかな、と思って作ってみた。ruby のあれですね。

function attr_accessor(obj, name, initialValue){
	var pname = "_" + name;
	obj.prototype[pname] = typeof initialValue === 'undefined' ? null : initialValue;
	obj.prototype.__defineGetter__(name, function() { return this[pname]; } );
	obj.prototype.__defineSetter__(name, function(val) { this[pname] = val; } );
};

// 使い方
TestObj = function(){
};
// オブジェクトにプロパティとGetter/Setter、初期値を付ける。
attr_accessor(TestObj, 'foo', 'Hello Accessor!');

var o = new TestObj();
alert('o.foo: ' + o.foo);

これでプロパティもばっちり隠蔽! o._foo とかでアクセスできちゃうけど、まあないよりいいだろ。
しかし、作って思ったが、あんまり意味ないな。微妙。。。