プログラム構造
そして私の心臓は、薄くて透明な皮膚の下で明るい赤色に輝き、彼らは私を呼び戻すために10ccのJavaScriptを投与しなければなりません。(私は血液中の毒素によく反応します。)ああ、それはあなたのえらを打ち破るだろう!

この章では、実際にプログラミングと呼べることを始めます。ここまでに見てきた名詞や文節を超えて、意味のある文章を表現できるところまでJavaScript言語のコマンドを拡張します。
式と文
第1章では、値を作り、それらに演算子を適用して新しい値を得ました。このように値を作成することが、あらゆるJavaScriptプログラムの主な内容です。しかし、その内容は、有用となるために、より大きな構造で構成される必要があります。それが、この章で取り扱う内容です。
値を生成するコードの断片は、式と呼ばれます。22
や"精神分析"
のように文字通りに書かれたすべての値は式です。括弧で囲まれた式も式であり、2つの式に適用された二項演算子や1つの式に適用された単項演算子も同様です。
これは、言語ベースのインターフェースの美しさの一部を示しています。式は、人間の言語における文節が入れ子になるのと同じように、他の式を含むことができます。文節はそれ自身の文節を含むことができ、以下同様です。これにより、任意に複雑な計算を記述する式を構築できます。
式が文節に対応する場合、JavaScriptの文は完全な文に対応します。プログラムは文のリストです。
最も単純な種類の文は、セミコロンが続く式です。これはプログラムです。
1;
!false;
しかし、これは役に立たないプログラムです。式は単に値を生成することに満足でき、その値は外側のコードで使用できます。しかし、文はそれ自体で独立しているため、世界に影響を与えない場合、役に立ちません。console.log
のように画面に何かを表示したり、後続の文に影響を与えるような方法でマシンの状態を変更したりする場合があります。これらの変更は、副作用と呼ばれます。前の例の文は、単に値1
とtrue
を生成してから、すぐにそれらを破棄します。これは、世界にまったく印象を残しません。このプログラムを実行しても、何も観察可能なことは起こりません。
場合によっては、JavaScriptでは文の末尾のセミコロンを省略できます。それ以外の場合は、そこにセミコロンがないと、次の行が同じ文の一部として扱われます。セミコロンを安全に省略できるタイミングのルールは、やや複雑でエラーが発生しやすいものです。そのため、本書では、セミコロンが必要なすべての文には必ずセミコロンを付与します。少なくとも、セミコロンの欠落の微妙な点についてより深く理解するまでは、同じようにすることをお勧めします。
束縛
プログラムはどのように内部状態を維持するのでしょうか?どのようにして物事を記憶するのでしょうか?古い値から新しい値を生成する方法を見てきましたが、これは古い値を変更するものではなく、新しい値はすぐに使用するか、再び消散してしまいます。値をキャッチして保持するために、JavaScriptには束縛または変数と呼ばれるものがあります。
let caught = 5 * 5;
これにより、2番目の種類の文が得られます。特別な単語(キーワード)let
は、この文が束縛を定義することを示します。その後に、束縛の名前が続き、すぐに値を付与したい場合は、=
演算子と式が続きます。
この例では、caught
という名前の束縛を作成し、それを使用して5に5を掛けた結果の数値を捉えます。
束縛が定義された後、その名前は式として使用できます。このような式の値は、束縛が現在保持している値です。以下に例を示します。
let ten = 10; console.log(ten * ten); // → 100
束縛がある値を指している場合、それはその値に永遠に結び付けられているという意味ではありません。=
演算子は、既存の束縛に対していつでも使用でき、現在の値からそれらを切断し、新しい値を指すようにすることができます。
let mood = "light"; console.log(mood); // → light mood = "dark"; console.log(mood); // → dark
束縛を箱ではなく触手として想像してください。束縛は値を包含するのではなく、値を掴みます。2つの束縛が同じ値を参照することができます。プログラムは、まだ参照を持っている値にのみアクセスできます。何かを記憶する必要がある場合は、それを保持するために触手を伸ばすか、既存の触手の1つをそれに再接続します。
別の例を見てみましょう。Luigiがあなたにまだ借りているドル数を記憶するために、束縛を作成します。彼が35ドルを返済したとき、この束縛に新しい値を付与します。
let luigisDebt = 140; luigisDebt = luigisDebt - 35; console.log(luigisDebt); // → 105
値を付与せずに束縛を定義すると、触手は何も掴むものがなく、宙に終わります。空の束縛の値を要求すると、値undefined
が得られます。
単一のlet
文で複数の束縛を定義できます。定義はカンマで区切る必要があります。
let one = 1, two = 2; console.log(one + two); // → 3
var
とconst
という単語も、let
と同様の方法で束縛を作成するために使用できます。
var name = "Ayda"; const greeting = "Hello "; console.log(greeting + name); // → Hello Ayda
これらの最初のvar
(「variable」の略)は、let
がまだ存在しなかった2015年より前のJavaScriptで束縛を宣言する方法でした。let
との正確な違いについては、次の章で説明します。今のところ、基本的には同じことを行うが、一部の状況で奇妙な動作をするため、この本ではほとんど使用しないことを覚えておいてください。
const
という単語は、定数を表します。これは、定数の束縛を定義し、それが存在している限り同じ値を指します。これは、値を簡単に後で参照できるように、値に名前を付けるだけの束縛に役立ちます。
束縛名
束縛名は、1つ以上の文字の任意のシーケンスにすることができます。数字は束縛名の一部になる可能性があります(たとえば、catch22
は有効な名前です)。ただし、名前は数字で始めることはできません。束縛名には、ドル記号($
)またはアンダースコア(_
)を含めることができますが、他の句読点または特殊文字は含めることはできません。
let
のような特別な意味を持つ単語は、キーワードであり、束縛名として使用することはできません。また、JavaScriptの将来のバージョンでの「使用のために予約されている」単語も多数あり、これらも束縛名として使用することはできません。キーワードと予約語の完全なリストはかなり長いです。
break case catch class const continue debugger default delete do else enum export extends false finally for function if implements import interface in instanceof let new package private protected public return static super switch this throw true try typeof var void while with yield
このリストを暗記することを心配しないでください。束縛を作成すると予期しない構文エラーが発生した場合は、予約語を定義しようとしていないかどうかを確認してください。
環境
特定の時点で存在する束縛とその値のコレクションは、環境と呼ばれます。プログラムが起動すると、この環境は空ではありません。常に言語標準の一部である束縛が含まれており、ほとんどの場合、周囲のシステムと対話する方法を提供する束縛もあります。たとえば、ブラウザには、現在ロードされているWebサイトと対話したり、マウスとキーボードの入力を読み取ったりするための関数があります。
関数
デフォルトの環境で提供される値の多くは、関数型です。関数とは、値でラップされたプログラムの一部です。このような値は、ラップされたプログラムを実行するために適用できます。たとえば、ブラウザ環境では、束縛prompt
は、ユーザー入力を求める小さなダイアログを表示する関数を保持します。これは次のように使用されます。
prompt("Enter passcode");

関数を実行することは、関数を呼び出す、呼ぶ、または適用すると呼ばれます。関数値を生成する式の後に括弧を付けることで、関数を呼び出すことができます。通常、関数を保持する束縛の名前を直接使用します。括弧内の値は、関数内のプログラムに渡されます。この例では、prompt
関数は、ダイアログボックスに表示するテキストとして、渡された文字列を使用します。関数に渡される値は引数と呼ばれます。異なる関数は、異なる数または異なる型の引数を必要とする場合があります。
prompt
関数は、結果として得られるダイアログの外観を制御できないため、現代のWebプログラミングではあまり使用されませんが、おもちゃのプログラムや実験では役立つ可能性があります。
console.log関数
例では、console.log
を使用して値を出力しました。ほとんどのJavaScriptシステム(すべての最新のWebブラウザとNode.jsを含む)は、何らかのテキスト出力デバイスに引数を出力するconsole.log
関数を提供しています。ブラウザでは、出力はJavaScriptコンソールに着地します。ブラウザインターフェースのこの部分はデフォルトで非表示になっていますが、ほとんどのブラウザではF12キーを押すか、Macではcommand-option-Iキーを押すと開きます。うまくいかない場合は、メニューで開発者ツールなどの名前の項目を検索してください。
この本のページで例(または独自のコード)を実行する場合、console.log
の出力は、ブラウザのJavaScriptコンソールではなく、例の後に表示されます。
let x = 30; console.log("the value of x is", x); // → the value of x is 30
束縛名にはピリオド文字を含めることはできませんが、console.log
には1つあります。これは、console.log
が単純な束縛ではなく、console
束縛によって保持されている値からlog
プロパティを取得する式であるためです。これが正確に何を意味するのかは、第4章で説明します。
戻り値
ダイアログボックスを表示したり、画面にテキストを書き込んだりすることは副作用です。多くの関数は、それらが生成する副作用のために役立ちます。関数は値を生成することもあり、その場合は有用であるために副作用を持つ必要はありません。たとえば、関数Math.max
は任意の数の数値引数を取り、最大の値を返します。
console.log(Math.max(2, 4)); // → 4
関数が値を生成する場合、その値を返すと言います。値を生成するものはすべてJavaScriptにおける式であり、関数呼び出しはより大きな式の中で使用できることを意味します。次のコードでは、Math.max
の反対であるMath.min
の呼び出しが、加算式の一部として使用されています。
console.log(Math.min(2, 4) + 100); // → 102
第3章では、独自の関数を記述する方法について説明します。
制御フロー
プログラムに複数の文が含まれている場合、文は物語のように上から下へと実行されます。たとえば、次のプログラムには2つの文があります。1つ目はユーザーに数値を尋ね、2つ目は、1つ目の後に実行され、その数の2乗を表示します。
let theNumber = Number(prompt("Pick a number")); console.log("Your number is the square root of " + theNumber * theNumber);
関数Number
は値を数値に変換します。prompt
の結果は文字列値であり、数値が必要なため、この変換が必要です。同様に、値をそれぞれの型に変換するString
とBoolean
という関数があります。
条件付き実行
すべてのプログラムが一直線であるとは限りません。たとえば、プログラムが当面の状況に基づいて適切な分岐を選択する分岐路を作成したい場合があります。これは条件付き実行と呼ばれます。
条件付き実行は、JavaScriptのif
キーワードを使用して作成されます。単純なケースでは、特定の条件が満たされた場合にのみ、一部のコードを実行したいとします。たとえば、入力が実際に数値である場合にのみ、入力の2乗を表示したい場合があります。
let theNumber = Number(prompt("Pick a number")); if (!Number.isNaN(theNumber)) { console.log("Your number is the square root of " + theNumber * theNumber); }
この変更により、「parrot」と入力すると、何も出力されません。
if
キーワードは、ブール式の値に応じて文を実行またはスキップします。決定する式は、キーワードの後、括弧で囲んで記述し、その後に実行する文を記述します。
Number.isNaN
関数は、与えられた引数がNaN
の場合にのみtrue
を返す標準のJavaScript関数です。Number
関数は、有効な数値を表さない文字列を与えると、NaN
を返します。したがって、条件は「theNumber
が非数でない限り、これを実行する」と翻訳されます。
この例では、if
の後の文が中括弧({
と}
)で囲まれています。中括弧は、任意の数の文をブロックと呼ばれる単一の文にグループ化するために使用できます。この場合、単一の文しか保持していないため、省略することもできましたが、それらが必要かどうかを考える必要がないように、ほとんどのJavaScriptプログラマーは、このようにラップされたすべての文で使用します。この本では、時折1行の文を除いて、ほとんどその慣例に従います。
if (1 + 1 == 2) console.log("It's true"); // → It's true
条件が真の場合に実行するコードだけでなく、他のケースを処理するコードが必要になることもよくあります。この代替パスは、図の2番目の矢印で表されます。else
キーワードをif
と一緒に使用して、2つの別個の代替実行パスを作成できます。
let theNumber = Number(prompt("Pick a number")); if (!Number.isNaN(theNumber)) { console.log("Your number is the square root of " + theNumber * theNumber); } else { console.log("Hey. Why didn't you give me a number?"); }
選択するパスが3つ以上ある場合は、複数のif
/else
ペアを「チェーン」でつなぐことができます。次に例を示します。
let num = Number(prompt("Pick a number")); if (num < 10) { console.log("Small"); } else if (num < 100) { console.log("Medium"); } else { console.log("Large"); }
プログラムはまず、num
が10未満かどうかを確認します。そうであれば、その分岐を選択し、"Small"
を表示して完了します。そうでない場合は、2番目のif
自体を含むelse
分岐に進みます。2番目の条件(< 100
)が満たされる場合、それは数値が少なくとも10以上100未満であることを意味し、"Medium"
が表示されます。そうでない場合は、2番目で最後のelse
分岐が選択されます。
whileおよびdoループ
0から12までのすべての偶数を出力するプログラムを考えてみましょう。これを記述する方法の1つは、次のとおりです。
console.log(0); console.log(2); console.log(4); console.log(6); console.log(8); console.log(10); console.log(12);
これは機能しますが、プログラムを作成する目的は、作業を減らすことではなく、増やすことではありません。1,000未満のすべての偶数が必要な場合、このアプローチは実行できません。必要なのは、コードの一部を複数回実行する方法です。この形式の制御フローはループと呼ばれます。
ループ制御フローを使用すると、以前にいたプログラムの特定のポイントに戻り、現在のプログラム状態でそれを繰り返すことができます。これをカウントするバインディングと組み合わせると、次のようになります。
let number = 0; while (number <= 12) { console.log(number); number = number + 2; } // → 0 // → 2 // … etcetera
while
キーワードで始まる文はループを作成します。while
という単語の後に、括弧で囲まれた式と文が続きます。これはif
とよく似ています。ループは、式がブール値に変換されたときにtrue
を与える値を生成する限り、その文に入り続けます。
number
バインディングは、バインディングがプログラムの進行状況を追跡する方法を示しています。ループが繰り返されるたびに、number
は前の値より2大きい値を取得します。繰り返しの開始時に、プログラムの作業が完了したかどうかを判断するために、12と比較されます。
実際に役立つ例として、210(2の10乗)の値を計算して表示するプログラムを作成できます。結果を追跡するためのバインディングと、この結果を2で何回乗算したかをカウントするためのバインディングの2つを使用します。ループは、2番目のバインディングがまだ10に達しているかどうかをテストし、達していない場合は、両方のバインディングを更新します。
let result = 1; let counter = 0; while (counter < 10) { result = result * 2; counter = counter + 1; } console.log(result); // → 1024
カウンターは1
から開始し、<= 10
をチェックすることもできましたが、第4章で明らかになる理由から、0からカウントすることに慣れておくことをお勧めします。
JavaScriptには、べき乗(2 ** 10
)の演算子もあり、実際のコードでこれを使用しますが、例が台無しになっていたでしょう。
do
ループは、while
ループに似た制御構造です。異なる点は1つだけです。do
ループは常に少なくとも1回は本体を実行し、その最初の実行後に停止する必要があるかどうかをテストし始めます。これを反映するために、テストはループの本体の後ろに表示されます。
let yourName; do { yourName = prompt("Who are you?"); } while (!yourName); console.log("Hello " + yourName);
このプログラムでは、名前を入力する必要があります。空の文字列ではないものを取得するまで、何度も繰り返し尋ねられます。!
演算子を適用すると、値を否定する前にブール型に変換され、""
を除くすべての文字列はtrue
に変換されます。つまり、空でない名前を入力するまでループが続きます。
コードのインデント
例では、より大きな文の一部である文の前にスペースを追加しています。これらのスペースは必須ではありません。コンピューターはそれらなしでもプログラムを問題なく受け入れます。実際、プログラムの改行でさえオプションです。必要に応じて、プログラムを1行の長い行として記述できます。
ブロック内のこのインデントの役割は、コードの構造を人間の読者に際立たせることです。新しいブロックが他のブロック内で開かれるコードでは、あるブロックがどこで終わり、別のブロックがどこで始まるかを見ることが難しくなる可能性があります。適切なインデントを使用すると、プログラムの視覚的な形状は、その中のブロックの形状に対応します。私は開いたブロックごとに2つのスペースを使用するのが好きですが、好みは異なります。4つのスペースを使用する人もいれば、タブ文字を使用する人もいます。重要なことは、新しいブロックごとに同じ量のスペースが追加されることです。
if (false != true) { console.log("That makes sense."); if (1 < 2) { console.log("No surprise there."); } }
ほとんどのコードエディタープログラム(この本のものも含む)は、新しい行を適切な量だけ自動的にインデントすることで役立ちます。
forループ
多くのループは、while
の例で示されているパターンに従います。まず、ループの進行状況を追跡するために「カウンター」バインディングが作成されます。次に、通常、カウンターが終了値に達したかどうかを確認するテスト式を使用したwhile
ループが来ます。ループ本体の最後に、カウンターが更新されて進捗状況を追跡します。
このパターンは非常に一般的であるため、JavaScriptや同様の言語では、わずかに短く、より包括的な形式であるfor
ループが提供されています。
for (let number = 0; number <= 12; number = number + 2) { console.log(number); } // → 0 // → 2 // … etcetera
このプログラムは、以前の偶数を出力する例とまったく同等です。唯一の変更点は、ループの「状態」に関連するすべての文が、for
の後にグループ化されていることです。
for
キーワードの後ろの括弧内には、2つのセミコロンが必要です。最初のセミコロンの前の部分はループを初期化し、通常はバインディングを定義します。2番目の部分は、ループを続行する必要があるかどうかをチェックする式です。最後の部分は、反復ごとにループの状態を更新します。多くの場合、これはwhile
構文よりも短く、明確です。
これは、while
の代わりにfor
を使用して210を計算するコードです。
let result = 1; for (let counter = 0; counter < 10; counter = counter + 1) { result = result * 2; } console.log(result); // → 1024
ループからの脱出
ループ条件がfalse
になることが、ループが終了する唯一の方法ではありません。break
文は、囲んでいるループから直ちにジャンプして脱出する効果があります。その使用法は、20以上でかつ7で割り切れる最初の数を見つける以下のプログラムで示されています。
for (let current = 20; ; current = current + 1) { if (current % 7 == 0) { console.log(current); break; } } // → 21
剰余(%
)演算子を使用すると、ある数が別の数で割り切れるかどうかを簡単にテストできます。割り切れる場合、除算の剰余はゼロになります。
この例のfor
構文には、ループの終了をチェックする部分がありません。これは、内部のbreak
文が実行されない限り、ループが停止しないことを意味します。
もしそのbreak
文を削除したり、誤って常にtrue
になる終了条件を記述したりすると、プログラムは無限ループに陥ります。無限ループに陥ったプログラムは決して実行を完了せず、通常は悪いことです。
このページの例のいずれかで無限ループを作成した場合、通常、数秒後にスクリプトを停止するかどうかを尋ねられます。それが失敗した場合は、作業中のタブを閉じて回復する必要があります。
continue
キーワードは、ループの進行に影響を与える点でbreak
に似ています。ループ本体でcontinue
が検出されると、制御は本体からジャンプして、ループの次の反復に進みます。
バインディングを簡潔に更新する
特にループの場合、プログラムは多くの場合、バインディングの前の値に基づいて値を保持するようにバインディングを「更新」する必要があります。
counter = counter + 1;
JavaScriptには、これに対するショートカットが用意されています。
counter += 1;
同様のショートカットは、result
を2倍にするためのresult *= 2
や、カウントダウンするためのcounter -= 1
など、他の多くの演算子でも機能します。
for (let number = 0; number <= 12; number += 2) { console.log(number); }
counter += 1
とcounter -= 1
の場合、さらに短い同等のものがあります。それはcounter++
とcounter--
です。
switchによる値のディスパッチ
if (x == "value1") action1(); else if (x == "value2") action2(); else if (x == "value3") action3(); else defaultAction();
switch
と呼ばれる構文があり、このような「ディスパッチ」をより直接的な方法で表現することを目的としています。残念ながら、JavaScriptがこれに使用している構文(C/Java系のプログラミング言語から継承したもの)はやや扱いにくいものです。if
文の連鎖の方がよく見えるかもしれません。以下に例を示します。
switch (prompt("What is the weather like?")) { case "rainy": console.log("Remember to bring an umbrella."); break; case "sunny": console.log("Dress lightly."); case "cloudy": console.log("Go outside."); break; default: console.log("Unknown weather type!"); break; }
switch
によって開かれたブロック内には、任意の数のcase
ラベルを配置できます。プログラムは、switch
に与えられた値に対応するラベル、または一致する値が見つからない場合はdefault
で実行を開始します。break
文に到達するまで、他のラベルをまたいでも実行を続けます。例の"sunny"
ケースのように、場合によっては、これを使用してケース間で一部のコードを共有できます(晴れと曇りの両方の天候で外出を推奨します)。ただし、注意してください。このようなbreak
を忘れると、実行したくないコードが実行されてしまうことがあります。
大文字と小文字の区別
バインディング名にはスペースを含めることはできませんが、バインディングが表すものを明確に記述するために複数の単語を使用すると便利なことがよくあります。複数の単語でバインディング名を記述するための選択肢は、ほぼ次のとおりです。
fuzzylittleturtle fuzzy_little_turtle FuzzyLittleTurtle fuzzyLittleTurtle
最初のスタイルは読みにくい場合があります。アンダースコアの外観はかなり好きですが、このスタイルは入力が少し面倒です。標準のJavaScript関数、およびほとんどのJavaScriptプログラマーは、最後のスタイルに従っています。最初の単語を除くすべての単語を大文字にします。そのような小さなことに慣れるのは難しくありません。また、名前付けスタイルが混ざったコードは読みにくい場合があるため、この規則に従います。
Number
関数のように、バインディングの最初の文字も大文字になっている場合があります。これは、この関数をコンストラクタとしてマークするために行われました。コンストラクタが何であるかは6章で明らかになります。今のところ、重要なのは、この見かけの一貫性の欠如に悩まされないことです。
コメント
多くの場合、生のコードは、プログラムが人間の読者に伝えたいすべての情報を伝えていないか、または人々が理解できないような暗号化された方法で伝えています。また、プログラムの一部として、関連する考えを含めたいだけの場合もあります。これがコメントの目的です。
コメントとは、プログラムの一部であるが、コンピューターによって完全に無視されるテキストのことです。JavaScriptには、コメントを記述する2つの方法があります。1行コメントを記述するには、2つのスラッシュ文字(//
)を使用し、その後にコメントテキストを続けます。
let accountBalance = calculateBalance(account); // It's a green hollow where a river sings accountBalance.adjust(); // Madly catching white tatters in the grass. let report = new Report(); // Where the sun on the proud mountain rings: addToReport(accountBalance, report); // It's a little valley, foaming like light in a glass.
//
コメントは、行末までしか続きません。/*
と*/
の間のテキストセクションは、改行が含まれているかどうかに関係なく、全体が無視されます。これは、ファイルまたはプログラムのチャンクに関する情報をブロックとして追加する場合に役立ちます。
/* I first found this number scrawled on the back of an old notebook. Since then, it has often dropped by, showing up in phone numbers and the serial numbers of products that I've bought. It obviously likes me, so I've decided to keep it. */ const myNumber = 11213;
まとめ
プログラムはステートメントから構成され、ステートメント自体がさらにステートメントを含む場合があることを理解しました。ステートメントは式を含む傾向があり、式自体はより小さな式から構成できます。
ステートメントを互いに続けて配置すると、上から下へ実行されるプログラムが得られます。条件付き(if
、else
、switch
)およびループ(while
、do
、for
)ステートメントを使用することにより、制御の流れに乱れを引き起こすことができます。
バインディングを使用してデータの一部に名前を付けて保存できます。また、プログラムの状態を追跡するのに役立ちます。環境とは、定義されているバインディングのセットのことです。JavaScriptシステムは、常に多くの便利な標準バインディングを環境に配置します。
関数は、プログラムの一部をカプセル化する特別な値です。functionName(argument1, argument2)
と記述することで呼び出すことができます。このような関数呼び出しは式であり、値を生成する場合があります。
演習
演習の解答をテストする方法がわからない場合は、はじめにを参照してください。
各演習は、問題の説明から始まります。この説明を読み、演習を解決してみてください。問題が発生した場合は、演習後のヒントを読むことを検討してください。演習の完全な解答は、https://eloquentjavascript.dokyumento.jp/codeでオンラインで確認できます。演習から何かを学びたい場合は、演習を解決した後、または少なくとも解決するために十分に努力して少し頭痛がするようになった後にのみ解答を見ることをお勧めします。
三角形をループする
次の三角形を出力するために、console.log
を7回呼び出すループを記述します。
# ## ### #### ##### ###### #######
文字列の長さを知るには、その後に.length
を記述すると便利かもしれません。
let abc = "abc"; console.log(abc.length); // → 3
ほとんどの演習には、演習を解決するために変更できるコードが含まれています。コードブロックをクリックして編集できることを忘れないでください。
// Your code here.
ヒントを表示...
まず、1から7までの数値を印刷するプログラムから始めます。これは、この章で前述した偶数印刷の例を少し変更することで導き出すことができ、そこでfor
ループが導入されました。
次に、数値とハッシュ文字の文字列との同等性を検討します。1から2にするには、1を加算します(+= 1
)。"#"
から"##"
にするには、文字を追加します(+= "#"
)。したがって、解決策は数値印刷プログラムに厳密に従うことができます。
FizzBuzz
console.log
を使用して、1から100までのすべての数値を2つの例外を除いて出力するプログラムを記述します。3で割り切れる数の場合は、数値の代わりに"Fizz"
と出力し、5で割り切れる数(3ではない)の場合は、代わりに"Buzz"
と出力します。
それが機能したら、3と5の両方で割り切れる数については"FizzBuzz"
と出力するようにプログラムを変更します(また、それらのいずれか1つのみで割り切れる数については、"Fizz"
または"Buzz"
を出力します)。
(これは実際には、プログラマーの候補者のかなりの割合をふるいにかけるために主張されてきた面接の質問です。したがって、それを解決した場合、あなたの労働市場価値は上がったばかりです。)
// Your code here.
ヒントを表示...
数値を反復処理することは明らかにループ処理であり、何を出力するかを選択することは条件付き実行の問題です。ある数が別の数で割り切れるかどうか(剰余がゼロかどうか)をチェックするために、剰余(%
)演算子を使用するコツを思い出してください。
最初のバージョンでは、すべての数値に対して3つの可能な結果があるため、if
/else if
/else
チェーンを作成する必要があります。
プログラムの2番目のバージョンには、単純な解決策と賢い解決策があります。単純な解決策は、与えられた条件を正確にテストするために、別の条件付き「分岐」を追加することです。賢い解決策としては、出力する単語または複数の単語を含む文字列を作成し、単語がない場合はこの単語または数値を、場合によっては||
演算子をうまく活用して出力します。
チェス盤
改行文字を使って行を区切り、8×8のグリッドを表す文字列を作成するプログラムを書いてください。グリッドの各位置には、スペースまたは「#」文字のいずれかがあります。文字はチェス盤を形成する必要があります。
この文字列をconsole.log
に渡すと、次のようなものが表示されるはずです。
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
このパターンを生成するプログラムができたら、バインディングsize = 8
を定義し、プログラムを変更して任意のsize
で動作するようにし、指定された幅と高さのグリッドを出力するようにしてください。
// Your code here.
ヒントを表示...
文字列は、空の文字列(""
)から始めて、文字を繰り返し追加することで作成できます。改行文字は"\n"
と記述されます。
2つの次元で動作させるには、ループの中にループが必要です。両方のループの本体を中括弧で囲んで、どこから始まりどこで終わるかをわかりやすくしてください。これらの本体を適切にインデントするようにしてください。ループの順序は、文字列を作成する順序(行ごと、左から右、上から下)に従う必要があります。したがって、外側のループは行を処理し、内側のループは行の文字を処理します。
進捗状況を追跡するために、2つのバインディングが必要です。指定された位置にスペースまたはハッシュ記号を配置するかどうかを知るには、2つのカウンターの合計が偶数かどうか(% 2
)をテストできます。
改行文字を追加して行を終了させるのは、行が作成された後に行う必要があるため、内側のループの後、外側のループの中でこれを行います。