質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

Q&A

解決済

4回答

453閲覧

Javascriptのループ文

SugiuraY

総合スコア317

JavaScript

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

0グッド

0クリップ

投稿2017/10/03 00:00

現在、Javascriptのループ文を学んでいるのですが、
以下の2点について、分からない部分があるため、どなたかご教示頂けますでしょうか。

  1. do Whileについて

JavaScript

1function printArray(a) { 2var len = a.length, i=0; 3if (len ==0) 4 console.log ("Empty Array"); 5 else { 6 do { 7 console.log(a[i]); 8 } while (++i< len); //この条件式がわからない 9 } 10}

通常のfor文等であれば、条件式は (var i=0; i< len ; i++){処理}で記載され
initialize/test/incrementの過程が直感的に理解できます。
つまり、testを評価しtrueとなる限り、処理が実行されるということになろうかと思います。

一方で、学んでいる書籍について、上記のwhileの条件式は(++i< len)となっており、test自体がincrementしており、直感的に理解できません。

これはtestの中にincrementを含めることも認められる記法であるということなのでしょうか?
また、(i=0 ;4 < i < 9 ; i+=2)のような複雑な条件を組むことは可能なのでしょうか?

  1. for文について

同じ書籍の例示に以下のような変わった例示があります。

JavaScript

1function tail (o) { 2for (; o.next; o=o.next) /*空文*/ //何がしたい?incrementもなくどうやってループしているの? 3return o;

解説によれば、以下の2点に触れられています。
・ループ変数は数値であるとは限らない
・リンクリストoの末尾(nextプロパティを持たない最初のオブジェクト)を返す

上記oは具体的にどういうオブジェクトを想定しているのでしょうか?
下記のようなものと思ったのですがundefinedが返されるため、ご教示願えますでしょうか?
var obj = {
a: {next:"hit"},b:{next:"hit"}, c:{here:"not hit"};
}
また、オブジェクトの構造を巡回して検査をする構造であるとすれば、数値の場合にi++でループさせているのに対して、incrementもなくどのようにしてループさせているのか構造が理解できないのですが、併せてご教示頂けると幸いです。

長文となりまた至らぬ点も多く、申し訳ございませんが、
宜しくお願い申し上げます。

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

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

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

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

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

kei344

2017/10/03 02:27

書籍については書籍名、版があればその数字、当該ページ番号を提示されたほうが良いと思います。
guest

回答4

0

1) do Whileについて

これはtestの中にincrementを含めることも認められる記法であるということなのでしょうか?

はい。認められます。言ってみればforのtestのiにだってincrementしても動作します。incrementはあくまで「ここまで処理が来たらこの変数に1を足す」という記述なので、どこにだって書けます。

また、(i=0 ;4 < i < 9 ; i+=2)のような複雑な条件を組むことは可能なのでしょうか?

i+=2は大丈夫ですが、4 < i < 9は無理です。この場合2つの条件に分けて4 < i && i < 9と書きます。ちなみにこの処理だといきなりテストに失敗してforに入らないです。

2) for文について

リンクリストというのは、「次のオブジェクトへの参照を持っているオブジェクトの一連の繋がり」です。

JavaScript

1 2var a = {value:1}; 3var b = {value:5}; 4var c = {value:10}; 5a.next = b; // aのnextにbを入れる 6b.next = c; // bのnextにcを入れる 7c.next = null; // cで終わりにするためnextはnullとする 8 9function tail (o) { 10 for (; o.next; o=o.next); // aのnextはb、bのnextはc、cのnextはnullなのでそこで処理が止まる 11 return o; // oにはcが入っている 12} 13 14var t = tail(a); // aから繋がりを探していき、nextがnullなオブジェクト、つまりcが返される

ちなみに上記の例において、c.nextaを入れると無限循環リストが出来上がります。永遠にnextを回り続けるリストなので、強制的に終了させるまでずっとループします。

投稿2017/10/03 00:35

編集2017/10/03 00:39
masaya_ohashi

総合スコア9206

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

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

SugiuraY

2017/10/03 04:36

masaya_ohashisama様 なるほど、リンクリストのことがよく分かりました。オブジェクトのなかに他のオブジェクトのプロティ(参照)を格納するという使い方をしたことがなかったのでいろいろな意味で勉強になりました。 宜しくお願い申し上げます。
guest

0

ベストアンサー

つまり、testを評価しtrueとなる限り、処理が実行されるということになろうかと思います。

インクリメントに限らず、何をしようが、この考え方のままです。
この例なら++i<lenを評価してtrueならループします。
i=1,len=3なら2<3でtrueです。評価の過程でiには2が再代入されます。

例えばこれも動きます

js

1 2let i=0; 3let len=5; 4do{ 5 console.log("do.") 6 7}while( 8 console.log("cond."+i), 9 ++i<len 10)

また、(i=0 ;4 < i < 9 ; i+=2)のような複雑な条件を組むことは可能なのでしょうか?

式なら何書いてもいいです。

ちなみに4 < i < 9(4 < i) < 9と解釈され、
(true または false) < 9となり、結局常にtrueなので、
意図したようには動きません。

こういう構造です。
{value:1, next:{value:2, next:{value:3}}}

仮にこれが初期値だとすると

js

1for (; o.next; o=o.next)

においてo

js

1{value:1, next:{value:2, next:{value:3}}} 2{value:2, next:{value:3}} 3{value:3}

と遷移しますね。

incrementもなくどのようにしてループさせているのか

インクリメントはループ成立のための魔法の言葉ではありません。
ループが続くのは条件式がtrueと評価されるからで、
ループが終わるのは条件式がfalseと評価されるからです。

for文は、

js

1for ([初期化式]; [条件式]; [更新式]) 2

という構造で、条件式が比較演算子を使っている必要もないし、
更新式がインクリメント演算子を使う必要もないです。

投稿2017/10/03 01:07

ozwk

総合スコア13521

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

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

SugiuraY

2017/10/03 04:24

ozwk様 ご回答有難うございます。なんとなく制御文について構文のように覚えていたことについて、丁寧にご説明頂きとてもよく分かりました。 一点だけ確認なのですが、もともと先入観でdo while (test)もfor(;;test)もtestについて、更新するための式(例えばi++)だけとおもっていましたが、 while( console.log("cond."+i), ++i<len )や for (; o.next; o=o.next,console.log(o))/*空文*/; のように処理を記載しても構わのですね。。 大変勉強になりました、心より感謝です。 宜しくお願い申し上げます。
guest

0

念の為・・・

for(i=0 ; 4< i < 9 ; i+=2){
は文法的には間違いではありませんが、おそらく質問者さんが期待する動作ではありません
test句について、式は左から順に評価されます

まずはi=0のとき、(4<0)が評価されfalse、それが(false<9)なのでtrueになります。
従ってiに2が足されループし、(4<2)=false,(false<9)=true
(4<4)=false,(false<9)=true,(4<6)=true,(true<9)=true,・・・・
となり結局ずっとtrueなので永久ループします

あらためて、iが4より大きく、9より小さいなら
4<i && i<9と書くべきです。
ただしi=0が、(4<i && i<9)を評価した時点で4<0=false && 0<9=true →false
なのでループしません。つまりやる意味はありません

いずれにしても、4<i<9的な書き方や評価をする意味がないということです

投稿2017/10/03 01:26

yambejp

総合スコア114814

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

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

SugiuraY

2017/10/03 03:46

yambejp様 ご回答頂き誠に有難うございます。 確かに永久ループしていまいました、どのようなロジックなのかと不思議に思っていたのですが、ご指摘の内容で納得を致しました。どうしても、特定の範囲で実行したいのであれば、初期値と条件式をうまく組み合わせて実行すればよいということなのでしょう。例:(i=4; i<9;i+=2) 宜しくお願い申し上げます。
guest

0

++iは前置インクリメントと呼ばれるもので、iの値を返す前にiに1を加えます。
なので、

javascript

1i++; 2i < len;

と同様の意味です。

o.nextについては、たぶん入出力的なオブジェクトなのかなあ、と。
oを無理やり再現するならこんな感じ。

javascript

1var o1 = { 2 next: null 3} 4var o2 = { 5 next: o1, 6 value: 'hoge' 7} 8var o3 = { 9 next: o2, 10 value: 'fuga' 11} 12var o = o3; 13o.next; //o2

投稿2017/10/03 00:57

Lhankor_Mhy

総合スコア36085

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

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

SugiuraY

2017/10/03 04:30

ご回答有難うございます。 確かに条件式について以下のとおりでも同じように動作しました。 i++; i < len; これは i++<len でも同じようにtrueである限り変数iに+1ずつ加算されて評価しており、分けて記載する式と等価であるということなのですね、 オブジェクトについては、書籍にはこれ以上の情報はないのですが、ozwk様が記載のとおり、再帰的な構造のデータなのかと印象を受けました。 宜しくお願い申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問