ECMAScript4 の動的性

2008/1/17追記。ごめんなさい。この話、ActionScript 3と同じみたいですね。

JavaScript1(ECMAScript3)の場合、

var DDD = function() {
};
DDD.prototype = {
	main: function() {
		print("Hello");
	}
};

var d = new DDD();
d.main();

d.main = function() {
	print("Replaced");
};
d.main();

という感じで、DDDのmainというメソッドは差し替え可能です。基本的に、何でもかんでも差し替え可能な言語です。

JavaScript2(ECMAScript4)の場合、上記の構文も使えますが、class を使った場合、

class NormalClass1 {
	function main() {
		print("Hello");
	}
}
var nc1 = new NormalClass1();
nc1.main = function() { print("Replaced"); }

はエラーです。

dynamic class DynamicClass1 {
	function main() {
		print("Hello");
	}
}
var dc1 = new DynamicClass1();
dc1.main = function() { print("Replaced"); }

dynamic class にしてもだめです。

class NormalClass2 {
	var main = function() {
		print("Hello");
	}
}
var nc2 = new NormalClass2();
nc2.main = function() { print("Replaced"); }

はOKです。しかし、

nc2.main2 = function() { print("Replaced"); }

は普通の class はメンバ変数の追加が禁止されているので、NGです。

dynamic class DynamicClass2 {
	var main = function() {
		print("Hello");
	}
}
var dc2 = new DynamicClass2();
dc2.main2 = function() { print("Replaced"); }

は dynamic class なのでOKです。

そして、nc2 にメソッドを追加したい時は、なんと、prototype が使えまして、

NormalClass1.prototype.main2 = function() { print("Replaced"); }
nc1.main2();
NormalClass2.prototype.main2 = function() { print("Replaced"); }
nc2.main2();

がOKなんです。dynamic class でなくても、prototype があるので、メンバ変数やメソッドが追加できちゃうんです。不思議な言語です。