「もしも自分が Javascript っぽい言語をゼロから設計するとしたら?」
というテーマで悶々と妄想を膨らませていたら, なんか新しい言語のようなものが出来たので, 仕様(というよりコード例)をしたためていきたいと思います.
見てくれは Javascript っぽいですが, 本家が プロトタイプベース オブジェクト指向なのに対して, この言語は クラスベース なオブジェクト指向になっています.
私がかじったことのある言語は Java, PHP, Perl, Javascript 程度なので「この設計思想は○○(既知の言語)と同じだよね」的なツッコミどころは大いにあるのではないかと...(; ・`д・´)
値の表現いろいろ
このへんは Javascript と全く同じ見た目です.
var num = 123; // 整数
var str = "hogehoge"; // 文字列
var isValid = false; // 真偽値
var arr = [-10, "asdf", "xyz", 7]; // 配列
var map = {"aaa": 123, "bbb": true, "ccc": 1.5}; // マップ
var func = function () { // 関数
console.log("Hello World!");
};
この言語では Javascript で object と呼んでいる概念を「マップ」型と呼びます.
すべてがオブジェクトになる
Java で言うところの「プリミティブ型」, あるいは PHP や Perl で言うところの「スカラー型」という概念はありません. すべての値がオブジェクトです.
getClass()
というインスタンスメソッドを使って, そのオブジェクトが属するクラスを調べることができます. (返り値は Class クラスのインスタンスです)
ちなみに console.log()
については今のところは「引数に指定した値を出力するためのおまじない」ということにしてください.
var num = 123;
var str = "hogehoge";
var isValid = false;
var arr = [-10, "asdf", 7, "xyz"];
var map = {"aaa": 123, "bbb": true, "ccc": 1.5};
var func = function () {
console.log("Hello World!");
};
console.log(num.getClass() === Integer); // true
console.log(str.getClass() === String); // true
console.log(isValid.getClass() === Boolean); // true
console.log(arr.getClass() === Array); // true
console.log(obj.getClass() === Map); // true
console.log(func.getClass() === Function); // true
クラスもオブジェクト
すべてのクラスは Class クラスのインスタンスなので, 上の例と同じく getClass() を実行した場合, 結果はすべて Class になります.
console.log(Integer.getClass() === Class); // true
console.log(String.getClass() === Class); // true
console.log(Boolean.getClass() === Class); // true
console.log(Array.getClass() === Class); // true
console.log(Map.getClass() === Class); // true
console.log(Function.getClass() === Class); // true
console.log(Class.getClass() === Class); // true (※Class そのものも Class クラスのインスタンス)
Integer
や String
などは言語仕様で定められた定義済みの変数です. (PHP で言うところの $_SERVER
や $_ENV
みたいなもの)
インスタンスやクラスを生成する
とあるクラスのインスタンスを生成するには, 以下のように書きます.
Javascript と同じですね.
var obj = new HogeHoge();
さきほど解説した通り, すべてのクラスは Class クラスのインスタンスです. そのため新しいクラスの定義も new で行います.
コンストラクタの第 1 引数に親クラス, 第 2 引数にクラスを定義するためのマップを指定します.
親クラスを指定しない場合は第 1 引数に Object を指定します. (あるいは第 1 引数を省略できるようにしたほうが良いかもしれない)
// 新しいクラス HogeHoge を作成
var HogeHoge = new Class(Object, {
"sayHello": function () {
console.log("Hello!");
}
});
// HogeHoge を継承したクラス FugaFuga を作成
var FugaFuga = new Class(HogeHoge, {
"sayGoodbye": function () {
console.log("Goodbye!");
}
});
var obj = new FugaFuga();
console.log(obj.sayHello()); // "Hello!"
console.log(obj.sayGoodbye()); // "Goodbye!"
関数
だいたい Javascript と同じ.
var square = function (num) {
return num * num;
};
console.log(square(10)); // 100
console.log(square("hoge")); // 0 (暗黙の型変換)
ただし Javascript と違い, このようにタイプヒンティングを付与することも出来ます.
var square = function (Integer num) {
return num * num;
};
console.log(square(10)); // 100
console.log(square("hoge")); // 実行時エラー
返り値を指定することも出来ます.
var formatPosNeg = function (Integer num) : String {
return (0 <= num) ? "positive" : "negative";
};
console.log(formatPosNeg(-5)); // "negative"
var invalidFunc = function (Integer num) : String {
return num;
};
console.log(invalidFunc(1)); // 返り値の型が String でないので実行時エラー
引数の Integer
の部分は Class クラスのインスタンスであれば何でも良いので, 例えば以下のようにも書けます. (実用性はありませんが)
var test = function () {
return Integer;
};
var formatPosNeg = function (test() num) : String {
return (0 <= num) ? "positive" : "negative";
};
console.log(formatPosNeg(-5)); // "negative"
次回は 配列編 です.
- Javascript っぽい新しい言語を妄想してみた ← イマココ
- Javascript っぽい新しい言語を妄想してみた【配列編】
- Javascript っぽい新しい言語を妄想してみた【マップ編】