複数の文を { ... } で囲むことにより、ひとつの文として扱うことができます。これを複文またはブロックと呼びます。
{ xx = 3; yy = 5; zz = xx + yy; }
変数の使用開始を明示的に宣言するには、var を用います。
var xx = 5; var yy = 8; var zz = xx + yy;
ES2015(ES6) からは、var の後継として let がサポートされました。let で定義した変数は、そのブロックの中だけで有効な局所変数となります。これにより、ブロック内で使用する変数が、ブロック外の変数の値を誤って上書きしてしまうリスクを低減することができます。Chrome 41, Firefox 44, Internet Explorer 11, Edge 12, Opera 17 から使用可能です。
var a = 3; let b = 3; { var a = 5; let b = 5; } console.log(a); // 5 (ブロック内で上書きされてしまう) console.log(b); // 3 (ブロック内で上書きされない)
for文 で使用する変数にも let を用いることで、ループ変数をより安全に使用することができます。
for (let i = 0; i < 10; i++) { console.log(i); }
ES6(ES2015) ではまた、定数を定義する const がサポートされました。const を用いて定義された定数に値を代入しようとすると、TypeError が発生します。Chrome 21, Firefox 36, Internet Explorer 11, Edge 12, Opera 12, Safari 5.1 から使用可能です。
const a = 5;
a = 8; // TypeError
expression が真であれば statements1 を、さもなくば statements2 を実行します。例えば次の例では、変数 n の値が 10 より小さければ、Small! を、さもなくば Big! を表示します。
n = 5; if (n < 10) { alert("Small!"); } else { alert("Big!"); }
else 以降は記述しない場合もあります。
if (n < 10) { alert("Small!"); }
次のような書き方もできます。
if (n < 10) { alert("Small!"); // 10より小さければ Small! を } else if (n > 20) { alert("Big!"); // 20より大きければ Big! を } else { alert("Normal"); // さもなくば Normal を表示 }
expression の値に応じて処理を振り分けます。次の例では、n の値が 1 なら One を、2 なら Tow を、3 か 4 なら Three or Four を、それ以外なら Other を表示します。
n = 2; switch (n) { case 1: alert("One"); break; case 2: alert("Two"); break; case 3: case 4: alert("Three or Four"); break; default: alert("Other"); break; }
break は statements の終わりを意味します。書き忘れると、次の case の statements まで実行されます。下記の例では、n が 1 の時、One と Two と Other が表示されます。
n = 1; switch (n) { case 1: alert("One"); case 2: alert("Two"); default: alert("Other"); }
expression が真である間、statements を繰り返します。次の例では n が 10 未満の間処理を繰り返し、0123456789 と表示します。
n = 0; while (n < 10) { console.log(n); n++; }
expression が真である間、statements を繰り返します。次の例では 0123456789 と表示されます。最初から expression が偽であっても、statements が少なくとも1回は実行される点が while (...) {...} と異なります。
n = 0; do { console.log(n); n++; } while (n < 10);
最初に expression1 を実行し、次に、statements と expression3 を expression2 が真である間繰り返します。次の例は10回繰り返す処理の典型的な例で、0123456789 と表示されます。
for (i = 0; i < 10; i++) { console.log(i); }
配列のすべての要素に関する処理を行います。次の例では BlueRedYellow が表示されます。
xx = [ "Blue", "Red", "Yellow" ]; for (i in xx) { console.log(xx[i]); }
オブジェクト に対して使用することもできます。オブジェクトの場合、順序は不定でしたが、ES2020 からは順序が保障されるようになりました。
var data = { name: "Yamada", age: 26, country: "Japan" }; for (var d in data) { console.log(d, data[d]); }
for を用いてオブジェクトが持つ属性の一覧を調べることもできます。下記の例では、navigator オブジェクトが持つ属性の一覧を表示します。ただし、これで調べられない属性(DontEnum属性を持つ属性)もあります。
for (var attr in navigator) { console.log(attr); }
ES6(ES2015) では、for (... of ...) のループがサポートされました。Map や Set をはじめとして、イテラブルなオブジェクトに対するループを実現します。
var set = new Set(); set.add("Tanaka"); set.add("Suzuki"); for (var value of set) { console.log(value); }
break は、最も内側の for、while、do ループや、switch 文の case 節を抜けます。次の例では、01234 と表示されます。
for (var i = 0; i < 10; i++) { if (i == 5) { break; } console.log(i); }
label は入れ子になったループを一度に抜けたい場合に用います。次の例では、xx が 20 より大きくなったときに、外側の for ループを抜けます。
abc: for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { xx = i * 10 + j; if (xx > 20) { break abc; } console.log(xx + "<br>"); } }
ループ内の残りの処理をスキップし、もっとも内側の for, while, do ループの次のループを実行します。次の例では 5 がスキップされて 012346789 と表示されます。
for (var i = 0; i < 10; i++) { if (i == 5) { continue; } console.log(i); }
label を指定した場合は、ラベルで指定したループの次のループを実行します。
abc: for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { xx = i * 10 + j; if (xx == 55) { continue abc; } } }
スクリプト中の位置にラベルをつけます。ラベルは break 文や continue 文で参照します。JavaScript 1.2 以降で使用可能です。
label1: for (var i = 0; i < 10; i++) { for (var j = 0; j < 10; j++) { if (func(i, j) { break label1; } } }
obj で指定したオブジェクトについて処理を行います。例えば、次の例は、
console.log(document.bgColor); console.log(document.fgColor);
with を用いて、次のように書くことができます。
with (document) { console.log(bgColor); console.log(fgColor); }
try, catch, finally は、JavaScript 1.4(ES3) で定義された構文で、例外処理を扱う際に使用されます。try { ... } の中でエラーが発生し、throw によって例外が投げられると、try { ... } の残りの処理はスキップされ、catch { ... } の処理が実行されます。finally { ... } の処理は例外の有無に関わらず実行されます。
try { error = doSomething(); if (error) { throw "myException"; } // エラーが発生するとこの部分の処理はスキップされます } catch (e) { // 例外が発生するとこの部分の処理が実行されます console.log(e); // "myException" } finally { // この部分の処理は例外発生の有無に関わらず実行されます console.log("finally"); }
ES2019(ES10) では、catch の引数を省略できるようになりました。
try { : } catch { : }
モジュールは、ES6(ES2015) でサポートされた機能で、PHP の require や Python の import と同様に、スクリプトから他のスクリプトファイルを読み込みます。Chrome 62, Safari 10.3 で使用可能です。
まず、読み込まれるファイル側で、公開する関数や変数を export 宣言します。
export function hello_world() { alert("Hello world!!"); }
上記で公開(エクスポート)された関数を、別のスクリプトファイルから import します。
import { hello_world } from "./module.js"; hello_world();
これを、HTML ファイルから呼び出します。ES6 modules を使用するスクリプトは type="module" 属性をつけて呼び出します。
<script type="module" src="test.js"></script>
外部に公開する変数や関数などを宣言します。
export var a1 = 5; // 変数 a1 をエクスポートする export let a2 = 5; // 変数 a2 をエクスポートする export const a3 = 5; // 定数 a3 をエクスポートする export function f1() {...} // 関数 f1 をエクスポートする
外部ファイルから、エクスポートされた変数や関数などを読み込みます。
import "./module.js"; // module.js からエクスポートされているものすべてをインポートする import { a1, a2 } from "./module.js"; // module.js から a1 と a2 をインポートする import { a1 as b1, a2 as b2 } from "./module.js"; // a1 を b1、a2 を b2 という名前でインポートする import * as mod from "./module.js"; // mod という名前でインポートする (mod.a1, mod.a2, ...)
ES2020 からは、ダイナミックインポートがサポートされました。モジュールを非同期にインポートし、インポートが完了した際に関数を実行することができます。
import("./module.js").then(mod => { console.log(mod.a1); });
ES2020 ではまた、import したものを直接 export することも可能となりました。
import * as mod from "./module.js"; // この2行を export { mod }; ↓ export * as mod from "./module.js"; // 1行で記述できる
ES2020 ではまた、import.meta オブジェクトがサポートされました。インポートされたモジュールの URL などのメタ情報を保持します。
console.log(import.meta);
EC5.1 で追加された機能で、ブラウザのデバッガ機能を使用する場合のブレークポイントを設定します。[F12] キー(Mac の場合は [Command]+[Option]+i) で開発ツールを開いた状態で下記を実行すると、debugger の箇所で実行が止まり、デバッグモードになります。変数やコンソールログを確認しながら、ステップ実行することも可能です。
console.log("A"); console.log("B"); debugger; console.log("C"); console.log("D");
JavaScript では goto 文はサポートされていません。