Help us understand the problem. What is going on with this article?

配列名にnameを使用するとfor-inで期待の動作をしない問題

More than 3 years have passed since last update.

下記コードの様にJavaScriptでfor-inで回して順に配列の中身を順に取り出そうとするも配列の要素の1字ずつが取り出されてしまう。

<script>
    var name = ['山田', '佐藤', '鈴木'];
    for(var i in name) {
        document.write(name[i] + 'です。' + '<br>');
    }
</script>

出力結果

山です。
田です。
,です。
佐です。
藤です。
,です。
鈴です。
木です。

勿論、期待していた出力結果は以下の通りです。

出力結果

山田です。
佐藤です。
鈴木です。

まずnameの変数名をname1とかに変えてみる

<script>
    var name1 = ['山田', '佐藤', '鈴木'];
    for(var i in name1) {
        document.write(name1[i] + 'です。' + '<br>');
    }
</script>

出力結果

山田です。
佐藤です。
鈴木です。

期待通りの出力がされた様です。

しかしこれだと何故このような結果に至ったのか、何故変数名をnameをname1に変えると上手くいくのかが納得がいかなかった為、もう少し調査してみました。

するとこんな仕様が見つかりました。
https://developer.mozilla.org/ja/docs/Web/API/Window/name

これによると、window.nameというグローバルオブジェクトwindowのプロパティがあるということです。
つまりこれが何を意味しているのかというと、変数名をnameにしてしまうとグローバル変数であるwindow.nameと衝突してしまうということです。
※name1に変数名を変更すると衝突自体は回避出来る

そして、window.nameは仕様によるとString型に型変換されてしまう為、
window.name = ['山田', '佐藤', '鈴木']
としてしまうと、配列の各要素が取り出されるのではなく、1文字ずつが取り出されてしまうという結果に至るわけです。
※そもそもfor-inだとランダムに要素が取り出される可能性があるので、順番を変えたくない場合には適しません。

対処法

即時関数で囲った上でローカル変数を定義し、for-inではなく単純にfor文を利用する方法が一番簡単な解決法かと思います。
これによりwindow.nameとの衝突を回避出来るハズです。

<script>
(function () {  
  var name = ['山田', '佐藤', '鈴木'];

  for (var i = 0, l = name.length; i < l; ++i) {
    document.write(name[i] + 'です。' + '<br>');
  }
}());
</script>

参考ページ
https://teratail.com/questions/16647

y-natsui
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした