for..of と for..in 文

配列に使ってみる

for..infor..ofを配列に対して使ってみましょう。

let list = [ 100, "taro", true];
for (let key in list) {
  console.log(key);
}
for (let val of list) {
  console.log(val);
}
$ node main.js 
0
1
2
100
taro
true

for..inはイテレーターのキーを順に扱うようなので配列のキー(インデックス)である0, 1, 2が出力されていますね。
for..ofは配列の値が出力されています。

少し気になったのはトランスパイルしたあとのJavaScriptのソースが以下のようになっています。
JavaScriptにもfor..ofはあるのですが、なぜか違う書き方に変わっています。

var list = [100, "taro", true];
for (var key in list) {
    console.log(key);
}
for (var _i = 0, list_1 = list; _i < list_1.length; _i++) {
    var val = list_1[_i];
    console.log(val);
}

これはどうやらトランスパイルのターゲットがES6未満になっていることが原因のようです。
for..ofが導入されたのはES6からのようなので。

ただ、tsconfig.jsonのtartgetで”ES6″を指定してみても、結果は変わりませんでした。
tsconfig.json の設定がちゃんと読み込めていないのか、正しい結果なのか、はわかりません(今は深追いしない)。

$ npx tsc main.ts のようにtsファイル名を指定するとtsconfig.jsonが読み込まれないようです。
$ npx tsc でトランスパイルしたところ次のように for..of が使われました。

"use strict";
let list = [100, "taro", true];
for (let key in list) {
    console.log(key);
}
for (let val of list) {
    console.log(val);
}

オブジェクトには使えるか?

for..infor..ofの配列への使い方がわかりました。
では例えば、以下のようなオブジェクトに対して使った場合、どのような結果になるのか見ていきましょう。

let list = {"id": 1, "name": "taro", "age": 30};
for (let key in list) {
  console.log(key);
}
for (let i of list) {
  console.log(i); // 4, 5, 6
}

結果としてはtype..ofがトランスパイルが次のエラーで失敗しました。
配列の時の結果を見ると、{ “id”: 1 } とか { “name”: “taro” }とかが取れそうですが、 type..ofはあくまでも配列に対して有効なようです。

main.ts:5:15 - error TS2495: Type '{ id: number; name: string; age: number; }' is not an array type or a string type.

5 for (let i of list) {
                ~~~~


Found 1 error in main.ts:5

type..inだけで試してみましょう。

let list = {"id": 1, "name": "taro", "age": 30};
for (let key in list) {
  console.log(key);
}

結果としては以下のようにキーが列挙しました。

$ node main.js 
id
name
age