3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Javascript っぽい新しい言語を妄想してみた【マップ編】

Last updated at Posted at 2015-08-31
  1. Javascript っぽい新しい言語を妄想してみた
  2. Javascript っぽい新しい言語を妄想してみた【配列編】
  3. Javascript っぽい新しい言語を妄想してみた【マップ編】 ← イマココ

あらすじ

「もしも自分が Javascript っぽい言語をゼロから設計するとしたら?」というテーマで以下のような言語を作ってみました. (名前はまだない)

  • 基本的な文法は Javascript と同じ.
  • オリジナルの Javascript が「プロトタイプベース」なのに対し, この言語は「クラスベース」なオブジェクト指向.
  • すべての値がオブジェクトである. 「スカラー型」あるいは「プリミティブ型」のような概念は存在せず, すべての値が何らかのクラスのインスタンス.
  • すべてのクラスは Class クラスのインスタンス. (※新しいクラスの定義は new Class() で行う)
  • 関数の表記はオリジナルの Javascript と同じだが, 引数や返り値のタイプヒンティングを付与することも出来る. (この辺りは Javascript よりもむしろ PHP7 に近い)

詳しいコードは 初回の記事 をご覧ください.

今回は「マップ」についての説明です.

基本形

Javascript における object の概念をこの言語では「マップ」と呼んでいます. 例えば以下のように書けます. Javascript と全く同じですね!

var map = {
    "foo": "aaaa",
    "bar": "bbbb",
    "baz": {
        "hoge": true,
        "fuga": false,
        "piyo": true,
    },
    "xxxx": ["a", "b", "c"],
    "yyyy": 100,
};

console.log(map["baz"]["hoge"]); // true

マップは Map クラスのインスタンスなので, 以下のようにメソッド呼び出しで書くこともできます.

var child = new Map();
child.put("hoge", true);
child.put("fuga", false);
child.put("piyo", true);

var map = new Map();
map.put("foo", "aaaa");
map.put("bar", "bbbb");
map.put("baz", child);
map.put("xxxx", ["a", "b", "c"]);
map.put("yyyy", 100);
map.put("new", 1.0);

console.log(map.get("baz").get("hoge")); // true

やっぱりジェネリック (総称) に対応

前回の配列編を読んでくださった方はおそらく想像がついているのではないかと思いますが, マップも配列と同様に型を指定することが出来ます.
コンストラクタの引数に Class 型オブジェクトを 2 つ指定することで, キーと値の型をそれぞれ指定することが出来ます.
以下のコードの Integer および String は, 言語仕様で定められたグローバル変数 (実態は Class クラスのインスタンス) です.

var map = new Map(Integer, String);
map.put(100, "asdf");
map.put(200, "xyz");
map.put(300, true); // 値が String 型ではないので実行時エラー

以下のようなシンタックスシュガーを使って同じことが表現できます.

var map = <Integer, String>{
    100: "asdf",
    200, "xyz"
};
map.put("hoge", "fuga"); // キーが Integer 型ではないので実行時エラー 

型を指定しない場合は, キーに String, 値に Object を指定したのと同じ意味になります.
以下の map1, map2, map3, map4 はすべて等価なオブジェクトです.

var map1 = <String, Object>{};
var map2 = {};
console.log(map1 == map2); // true

var map3 = new Map(String, Object);
var map4 = new Map();
console.log(map3 == map4);

(余談: 2 つのオブジェクトが「等価」かどうかのチェックは ==, 「同一」かどうかのチェックは === を使います)

例えマップの中身が同じでも, マップに指定された型が違う場合は等価にはなりません.

var map1 = <Integer, Object>{100: "hoge", 200: "fuga"};
var map2 = <Object, String>{100: "hoge", 200: "fuga"};
console.log(map1 == map2); // false

以上で Map 編は終了です. 次回は「クラス定義」編を予定しています. (内容はただいま構想中)

ちなみに ES6 ではかなりクラスベースっぽくなったとの噂ですが, 今のところ最新情報を追えておりません...

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?