\r\n\r\n\r\n```\r\n\r\n**出力結果**\r\n山です。\r\n田です。\r\n,です。\r\n佐です。\r\n藤です。\r\n,です。\r\n鈴です。\r\n木です。\r\n\r\n\r\nちなみに配列名をname以外にすると(例えばname1)の様にすると以下の様に期待通りの結果が得られるのですが、こうなる理由が分かりません。もしご存じの方がいらっしゃったら教えて頂けると幸いです。\r\n\r\n**期待する出力結果**\r\n山田です。\r\n佐藤です。\r\n鈴木です。\r\n\r\n検証ブラウザ\r\nChrome","answerCount":2,"upvoteCount":0,"datePublished":"2015-09-22T20:08:08.057Z","dateModified":"2015-09-22T20:10:03.596Z","acceptedAnswer":{"@type":"Answer","text":"とりあえず簡単に。「name」を使った場合特有の点を言うと、\r\n・nameがグローバルオブジェクトのプロパティとして、すでに存在している\r\n・グローバルオブジェクトのnameを参照してしまう\r\n・String型に強制される\r\nからです。\r\n\r\n「name1」でも文字列型に強制すれば同じことが起きます。\r\n```ここに言語を入力\r\nvar name1 = ['山田', '佐藤', '鈴木'];\r\nname1 += \"\";\r\nfor(var i in name1) {\r\n document.write(name1[i] + 'です。' + '
');\r\n}\r\n```\r\n\r\nそれから、配列にfor-inは絶対に使ってはいけません。for-inはオブジェクトに使うものです。配列に使ってもうまく動くことが多いですが、予期せぬ問題を引き起こす場合もあります。\r\n\r\nそこが分かっていらっしゃらないということは、JavaScript初心者の方ではないかと思います。しっかりした本で基礎をきちんと勉強したほうがいいと思います。","dateModified":"2015-09-22T20:39:09.992Z","datePublished":"2015-09-22T20:39:09.992Z","upvoteCount":3,"url":"https://teratail.com/questions/16647#reply-25913"},"suggestedAnswer":[{"@type":"Answer","text":"miu_ras さんの仰る通りなのですが、いくつか補足しておきます。\r\n\r\nグローバル変数はグローバルオブジェクト(`window`)のプロパティでもある為、グローバル変数 `name` は `window.name` と衝突します。\r\n`window.name` は String 型のプロパティとして定義されている為、String 型に強制的に変換されます。\r\nString 型は ES5 から配列のように参照可能になっており、`string[0]` は `string.charAt(0)` と同じ値を返します。\r\n従って、グローバル変数 `name` は String 型に変換され、`for-in` で1文字ずつ値を返すようになってしまいます。\r\n解決法としては関数内で変数を定義して下さい。\r\n変数名を変更することでも回避可能ですが、`window` のプロパティは新しい仕様が生まれる度に増えていく運命にあります。\r\n仕様が増える度に変数名が衝突する懸念があるのでローカル変数として定義した方が安全度が高いと思われます。\r\nOKWave で同様の回答をした事がある為、そちらも参考にどうぞ。\r\n- [JavaScriptをgoogle chromeで - JavaScript | 【OKWave】](http://okwave.jp/qa/q6404370.html)\r\n\r\n---\r\n\r\n`for-in` はプロトタイプ上のプロパティも拾う上、列挙順がランダムであるという性質があります。\r\n配列の繰り返し文は一般に 0 から順番にインクリメントして走査することを期待する為、`for-in` での走査は推奨されません。\r\n配列の繰り返しには `for` 文もしくは `Array.protoype.forEach` を使用して下さい。\r\n\r\n---\r\n\r\n解決の為のコード例を載せておきます。\r\n始めは難しく考えず、`for` 文を使うことをお勧めします。\r\n\r\n```JavaScript\r\n(function () { // window.name との衝突を避ける為、関数式で括る (いわゆる即時関数)\r\n var name = ['山田', '佐藤', '鈴木']; // ローカル変数を定義\r\n\r\n for (var i = 0, l = name.length; i < l; ++i) {\r\n document.write(name[i] + 'です。' + '
');\r\n }\r\n\r\n name.forEach(function (value) { // Array.protoype.forEach\r\n document.write(value + 'です。' + '
');\r\n });\r\n\r\n document.write(name.map(function (value) { // Array.protoype.map, Array.protoype.join\r\n return value + 'です。';\r\n }).join('
'));\r\n}());\r\n```","dateModified":"2015-09-23T02:37:55.517Z","datePublished":"2015-09-23T02:34:36.083Z","upvoteCount":2,"url":"https://teratail.com/questions/16647#reply-25920","comment":[{"@type":"Comment","text":"補足情報まで頂き有難うございます。\r\n是非参考にさせて頂きます。","datePublished":"2015-09-23T12:06:48.999Z","dateModified":"2015-09-23T12:06:48.999Z"}]}],"breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://teratail.com","name":"トップ"}},{"@type":"ListItem","position":2,"item":{"@id":"https://teratail.com/tags/JavaScript","name":"JavaScriptに関する質問"}},{"@type":"ListItem","position":3,"item":{"@id":"https://teratail.com/questions/16647","name":"JavaScriptの配列名にnameを使用すると期待の動作をしない"}}]}}}
質問するログイン新規登録

Q&A

解決済

2回答

4613閲覧

JavaScriptの配列名にnameを使用すると期待の動作をしない

y_natsui

総合スコア49

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2015/09/22 20:08

編集2015/09/22 20:10

0

0

JSで例えば以下の様に配列名をnameとして、for文で回す処理をするも出力結果が期待値と異なる。

JavaScript

1<!DOCTYPE html> 2<html> 3<head> 4<meta charset="UTF-8" /> 5<title>サンプルページ</title> 6</head> 7<body> 8<script type="text/javascript"> 9 var name = ['山田', '佐藤', '鈴木']; 10 for(var i in name) { 11 document.write(name[i] + 'です。' + '<br>'); 12 } 13</script> 14</body> 15</html>

出力結果
山です。
田です。
,です。
佐です。
藤です。
,です。
鈴です。
木です。

ちなみに配列名をname以外にすると(例えばname1)の様にすると以下の様に期待通りの結果が得られるのですが、こうなる理由が分かりません。もしご存じの方がいらっしゃったら教えて頂けると幸いです。

期待する出力結果
山田です。
佐藤です。
鈴木です。

検証ブラウザ
Chrome

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

とりあえず簡単に。「name」を使った場合特有の点を言うと、
・nameがグローバルオブジェクトのプロパティとして、すでに存在している
・グローバルオブジェクトのnameを参照してしまう
・String型に強制される
からです。

「name1」でも文字列型に強制すれば同じことが起きます。

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

それから、配列にfor-inは絶対に使ってはいけません。for-inはオブジェクトに使うものです。配列に使ってもうまく動くことが多いですが、予期せぬ問題を引き起こす場合もあります。

そこが分かっていらっしゃらないということは、JavaScript初心者の方ではないかと思います。しっかりした本で基礎をきちんと勉強したほうがいいと思います。

投稿2015/09/22 20:39

miu_ras

総合スコア902

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_natsui

2015/09/23 12:04

ご回答頂き有難うございました。 シンプルで分かりやすい回答を頂き有難うございます。 書籍の中のサンプルが期待の動作をしなかったので、やっとその理由が分かって助かりました。
guest

0

miu_ras さんの仰る通りなのですが、いくつか補足しておきます。

グローバル変数はグローバルオブジェクト(window)のプロパティでもある為、グローバル変数 namewindow.name と衝突します。
window.name は String 型のプロパティとして定義されている為、String 型に強制的に変換されます。
String 型は ES5 から配列のように参照可能になっており、string[0]string.charAt(0) と同じ値を返します。
従って、グローバル変数 name は String 型に変換され、for-in で1文字ずつ値を返すようになってしまいます。
解決法としては関数内で変数を定義して下さい。
変数名を変更することでも回避可能ですが、window のプロパティは新しい仕様が生まれる度に増えていく運命にあります。
仕様が増える度に変数名が衝突する懸念があるのでローカル変数として定義した方が安全度が高いと思われます。
OKWave で同様の回答をした事がある為、そちらも参考にどうぞ。


for-in はプロトタイプ上のプロパティも拾う上、列挙順がランダムであるという性質があります。
配列の繰り返し文は一般に 0 から順番にインクリメントして走査することを期待する為、for-in での走査は推奨されません。
配列の繰り返しには for 文もしくは Array.protoype.forEach を使用して下さい。


解決の為のコード例を載せておきます。
始めは難しく考えず、for 文を使うことをお勧めします。

JavaScript

1(function () { // window.name との衝突を避ける為、関数式で括る (いわゆる即時関数) 2 var name = ['山田', '佐藤', '鈴木']; // ローカル変数を定義 3 4 for (var i = 0, l = name.length; i < l; ++i) { 5 document.write(name[i] + 'です。' + '<br>'); 6 } 7 8 name.forEach(function (value) { // Array.protoype.forEach 9 document.write(value + 'です。' + '<br>'); 10 }); 11 12 document.write(name.map(function (value) { // Array.protoype.map, Array.protoype.join 13 return value + 'です。'; 14 }).join('<br>')); 15}());

投稿2015/09/23 02:34

編集2015/09/23 02:38
think49

総合スコア18196

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_natsui

2015/09/23 12:06

補足情報まで頂き有難うございます。 是非参考にさせて頂きます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問