JavaScriptでクロージャを利用するだけでは、immutableオブジェクトは実現できない

クロージャによるデータのカプセル化

JavaScript カプセル化ググると、「getterを使うことによってカプセル化を実現出来る」という記事が多かった。
こんなかんじ。

function createVector2D(_x,_y)
{
	return {
		x:function(){return _x;},
		y:function(){return _y;},
		length:function(){return Math.sqrt(_x*_x+_y*_y);}
	}
}
var v = createVector2D(1,0);
v.x();//1
v.length(); // 1.4142...

ふむ、たしかに、_xや_yは、クロージャによってカプセル化されている。
つまり、このオブジェクトのプロパティは変更できないように見える。

プロパティのカプセル化は結局出来ていない

私もこの方法は思いついたが、これだけでは、immutableオブジェクトとしては扱えず、プロパティの変更が出来てしまう。

var v = createVector2D(1,0);
v.x(); //1
v.x = function(){return 3;}
v.x(); //3
v.length();//1.4142...

xの値が変更されてしまった。
なぜか。


それは_xというデータをx()という関数によってカプセル化出来たが、今度はxというデータ(Functionのインスタンス)が外部から見えてしまう。
プロパティは変更可能なので、新しい関数を代入することによってオブジェクトを破壊的に操作することが出来る。


_xというデータをカプセル化するという意味では非常に有用だ。
しかし、オブジェクトの値は依然として変更可能であり、わざわざgetterを用意するぐらいなら、
そのままプロパティを定義する方がよい。