ちょっと変えてみた(書き方がめんどくさいので没)

他言語遣いの人にJSのカプセル化と継承を説明したい - 最遅メンヘル研究会の続き。prototypeプロパティを使ってもいいことにして、instanceofが使い物になるようにしてみた。

コンソールでやるためだけにWSH(JScript)で書いていますが、WSH#echo以外のコードはJavaScriptです。記事の内容としてはJavaScriptの話なので、JavaScriptタグにしています。

<?xml version="1.0" encoding="utf-8"?>
<job>
<script language="JScript"><![CDATA[
(function() {
	function extend(d, s) { for (var p in s) d[p] = s[p]; }

	function Sup() {}
	Sup.create = function(spec, my) {
		my = my || {};

		var that = new Sup();

		that.get_name = get_name;
		that.get_val  = get_val;
		that.plus_val = plus_val;

		my.name = spec.name;
		my.val = 0;

		function get_name() {
			return my.name;
		}

		function get_val() {
			return my.val;
		}

		function plus_val() {
			my.val = my.val + 1;
			return that;
		}

		return that;
	};

	function Sub() {};
	Sub.prototype = new Sup();
	Sub.create = function(spec, my) {
		my = my || {};

		var that = new Sub();
		extend(that, Sup.create(spec, my)); // Sub extends Sup

		that.plus_val  = plus_val; // @Override
		that.minus_val = minus_val;

		function plus_val() {
			my.val = my.val + 2;
			return that;
		}

		function minus_val() {
			my.val = my.val - 1;
			return that;
		}

		return that;
	};

	function Foo() {}
	Foo.prototype = new Sub();
	Foo.create = function(spec, my) {
		my = my || {};

		var that = new Foo();
		extend(that, Sub.create(spec, my)); // Foo extends Sub

		my.val = 2;

		return that;
	};

	var sup = Sup.create({name:'sup'});
	var sub = Sub.create({name:'sub'});
	var foo = Foo.create({name:'foo'});

	Number.prototype.zerofill = function(len) {
		return ((1 << len).toString(2) + this).slice(-len);
	};
	var ok = (function() {
		var i = 0;
		return function(d, s) { return [(i++).zerofill(2), d === s ? ' OK' : 'NG']; };
	})();

	WSH.echo(ok(sup instanceof Sup, true));
	WSH.echo(ok(sub instanceof Sup, true));
	WSH.echo(ok(sub instanceof Sub, true));
	WSH.echo(ok(foo instanceof Sup, true));
	WSH.echo(ok(foo instanceof Sub, true));
	WSH.echo(ok(foo instanceof Foo, true));

	WSH.echo(ok(sup.create, undefined));
	WSH.echo(ok(sub.create, undefined));

	WSH.echo(ok([ sup.get_name(), sup.plus_val().get_val()  ].join(':'), 'sup:1'));
	WSH.echo(ok([ sup.get_name(), sup.plus_val().get_val()  ].join(':'), 'sup:2'));
	WSH.echo(ok(sup.minus_val, undefined));
	WSH.echo(ok([ sub.get_name(), sub.plus_val().get_val()  ].join(':'), 'sub:2'));
	WSH.echo(ok([ sub.get_name(), sub.plus_val().get_val()  ].join(':'), 'sub:4'));
	WSH.echo(ok([ sub.get_name(), sub.minus_val().get_val() ].join(':'), 'sub:3'));
	WSH.echo(ok([ foo.get_name(), foo.plus_val().get_val()  ].join(':'), 'foo:4'));
	WSH.echo(ok([ foo.get_name(), foo.plus_val().get_val()  ].join(':'), 'foo:6'));
	WSH.echo(ok([ foo.get_name(), foo.minus_val().get_val() ].join(':'), 'foo:5'));

	var sb2 = Sub.create({name:'sb2'});
	WSH.echo(ok([ sb2.get_name(), sb2.plus_val().get_val()  ].join(':'), 'sb2:2'));
	WSH.echo(ok([ sub.get_name(), sub.plus_val().get_val()  ].join(':'), 'sub:5'));
})();
]]></script>
</job>