「JavaScript/制御構造」の版間の差分
削除された内容 追加された内容
語尾の統一 タグ: 2017年版ソースエディター |
cleanup タグ: 2017年版ソースエディター |
||
1 行
{{Nav}}
'''[[w:制御構造|制御構造]]'''
==
次のプログラムは、、
* ''n''が0より小さいときには「負の数」
* ''n''が0より大きいときには「正の数」
*
;[https://paiza.io/projects/PVQmLtgKSbojqVJ52Z7FLA?language=javascript 例]:<syntaxhighlight lang=js line>
"use strict";
const n = 0 / 0;
if (n < 0) {
} else if (n > 0) {
console.log("正の数");
} else if (n > 0) {
console.log("零");
} else
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
NaN
</syntaxhighlight>
: <code>0 / 0</code>は、除数がゼロであると考えれば無限大ですが、被除数がゼロと考えるとゼロというパラドックス持ちで、ISO/IEC/IEEE 60559:2011 ではこのケースを NaN 非数とします。
この様な、分岐を始めとする制御構造はプログラミングを行う上で欠かせません。
=== if-else ===
'''[[w:if文|if文]]'''( ''if statement'' )は「もし〜ならば」を表す条件分岐構文です。
if文では{{code|()}}の中に書かれた条件が [[JavaScript/truthy|truthy]] であるとき続く文が実行されます。
次のプログラムは、''n'' < 0(''n''が0より小さい)という条件が真であるときのみ「負の数」と表示します。
;[https://paiza.io/projects/MH-qBPF-5NoFfr8RE9pNgw?language=javascript 例]:<syntaxhighlight lang=
"use strict";
const n = -1;
if (n < 0) {
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
負の数
</syntaxhighlight>
if文のあとに'''else節'''( ''else clause'' )を置くと、else節の文はif文の条件が [[JavaScript/falsy|falsy]] であるときのみ実行されます。
次のプログラムは、''n'' < 0(''n''が0より小さい)という条件が真であれば「負の数」、さもなくば「自然数」と表示します<ref>計算機科学では一般に0を自然数に含め、曖昧さを避けたいときは非負整数とも言います</ref>。
;[https://paiza.io/projects/4xFIs20boohxUskXETRF5A?language=javascript 例]:<syntaxhighlight lang=js line>
"use strict";
const n = 0;
if (n < 0) {
} else {
console.log("自然数");
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
自然数
</syntaxhighlight>
if文とelse節をあわせてif/else文と呼びます
else節の文をif文とすることで、次のように何個もつらねることができます。
;[https://paiza.io/projects/eFR9IgcwfDGYVdzdSraJsg?language=javascript 例]:<syntaxhighlight lang=js line>
"use strict";
const n = 0;
if (n < 0) {
} else if (n > 0) {
console.log("正の数");
} else if (n == 0) {
console.log("零");
} else
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
零
</syntaxhighlight>
: このプログラムは''n'' < 0ならば「負の数」、そうでなく''n'' > 0ならば「正の数」、そうでなく''n'' == 0ならば「零」、そうでもないならば n の値が表示されます。
: <code>else if</code>という部分に注目してください。
: 何通りもの条件で処理を分岐したい場合は、このelse ifを何個も増やしていくことになります。
: if文やelse節の文はブロックである必要はありません。
: 単文(1つの文)しか入っていない場合は、次のように書いても同じことです。
;例:<syntaxhighlight lang=js line>
"use strict";
const n = 0;
if (n < 0) console.log("負の数");
else if (n
else if (n == 0) console.log("
else
</syntaxhighlight>
なお、この場合は条件演算子を用いて簡潔に書
;例:<syntaxhighlight lang=
"use strict";
const n = 0;
console.log(n < 0 ? "負の数"
: n > 0 ? "正の数"
: n == 0 ? "零"
: n);
</syntaxhighlight>
109 ⟶ 115行目:
if文の条件式はすべてtrueかfalseの[[JavaScript/Boolean|真偽値]]として評価されます。たとえば、数値の0は真偽値に変換するとfalseになるので<ref>falsy</ref>、次のif文のブロックは絶対に実行されません([[w:到達不能コード|デッドコード]])。
:<syntaxhighlight lang=
if (0) {
// たどり
}
</syntaxhighlight>
134 ⟶ 140行目:
if/else文を用いる場合は、
:<syntaxhighlight lang=
"use strict";
if (n % 2 == 0) {
} else {
console.log("奇数");
}
</syntaxhighlight>
145 ⟶ 152行目:
または
:<syntaxhighlight lang=
"use strict";
if (n % 2) {
} else {
console.log("偶数");
}
</syntaxhighlight>
156 ⟶ 164行目:
条件演算子を用いる場合は、
:<syntaxhighlight lang=
"use strict";
console.log(n % 2 == 0 ? "偶数"
: "奇数");
163 ⟶ 173行目:
または
:<syntaxhighlight lang=
"use strict";
console.log(n % 2 ? "奇数"
: "偶数");
170 ⟶ 182行目:
または
:<syntaxhighlight lang=
"use strict";
console.log((n % 2 ? "奇"
: "偶") + "数");
176 ⟶ 190行目:
または
:<syntaxhighlight lang=
"use strict";
console.log("偶奇"[n % 2] + "数");
</syntaxhighlight>
182 ⟶ 198行目:
=== if-else 文の構文===
:<syntaxhighlight lang=
if ( 条件式 ) 文1 [ else 文2 ]
</syntaxhighlight>
{{code|[}}から{{code|]}}までは省略可能を意味し、この場合は「else節は省略可能」を意味します。
=== switch ===
'''[[w:switch文|switch文]]'''
:<syntaxhighlight lang=js line>
"use strict";
if (keyCode == 37) {
} else if (keyCode == 38) {
console.log("↑");
} else if (keyCode == 39) {
console.log("→");
} else if (keyCode ==
} else {
console.log("?");
}
</syntaxhighlight>
これはswitch文を使って次のように書くことができます。
:<syntaxhighlight lang=
"use strict";
switch (keyCode) {
case 37:
console.log("←");
break;
case 38:
console.log("↑");
break;
case 39:
console.log("→");
break;
case 40:
console.log("↓");
break;
default:
console.log("?");
}
</syntaxhighlight>
必ずcase節の最後にbreak文を書くのを忘れないでください。
234 ⟶ 248行目:
switch文はここぞというときに使ってください<ref>JavaScriptのswitch文は、動的なのに静的なC言語の構文を倣ったので'''[[#switch文の限界と限界突破|コラム:switch文の限界と限界突破]]'''の様なハックを使わない限り恩恵を受けられません。</ref>。
:<syntaxhighlight lang=
"use strict";
console.log(
{
37: "←",
38: "↑",
39: "→",
40: "↓"
}[keyCode] || "?"
);
</syntaxhighlight>
=== switch 文の構文===
:<syntaxhighlight lang=
switch (式) {
case 値1 :
245 ⟶ 268行目:
case 値2 :
文2
case 値n :
文n
259 ⟶ 282行目:
この為、式に対応する範囲や正規表現を直接的に表現することはできません。
この制限はややトリッキーな方法で回避できます。
:<syntaxhighlight lang=
let age = prompt("年齢は?"),
text = "";
272 ⟶ 295行目:
</syntaxhighlight>
ポイントは
:<syntaxhighlight lang=
switch (true) {
</syntaxhighlight>
280 ⟶ 303行目:
}}
==
=== while ===
いよいよループの登場です。'''[[w:while文|while文]]'''( ''while statement'' )は条件が真である間、文を実行しつづけます。
;[https://paiza.io/projects/rmb98IyjUuJlXVceEotPtw?language=javascript 例]:<syntaxhighlight lang=js line>
"use strict";
let i = 0;
while (i < 10) {
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
0
1
2
3
4
5
6
7
8
9
</syntaxhighlight>
# strictモードは常に使うべきです。
#
# 変数''i''に0を代入
# ''i'' < 10がtrueでれば以下を実行します
#: そうでなければ、このwhile文の次に進みます
# ''i''を表示します
# ''i''を1増やします。
10回ループが回ると''i''が10になり、''i'' < 10がfalseになるのでループを抜けます。
302 ⟶ 341行目:
=== while 文の構文 ===
:<syntaxhighlight lang=
while ( 式 ) 文
</syntaxhighlight>
while文に与えられた式が truthy の間、繰り返し文を実行します。
=== do-while ===
'''[[w:do-while文|do-while文]]'''
:<syntaxhighlight lang=
let i = 0;
do {
320 ⟶ 358行目:
=== do-while 文の構文 ===
:<syntaxhighlight lang=
do 文 while ( 式 )
</syntaxhighlight>
まず文を無条件に実行し、while文に与えられた式が truthy の間、繰り返し文を実行します。
=== for ===
'''[[w:文|for文]]'''
let ''i'' = 0のような変数の初期化と、''i'' < 10のような条件式と、''i''++のような変数の更新を一行で書く制御構文です。
JavaScriptではwhile文やdo-while文はあまり使われませんが、for文はループを簡潔に書けるので非常に重宝します。
次のプログラムは0から9までの数字を表示します。
:<syntaxhighlight lang=
"use strict";
for (let i = 0; i < 10; i++) {
}
</syntaxhighlight>
: 最初の項、let ''i'' = 0はループに入る前に一度だけ実行されます。
結果、''i'' < 10がtruthyである間、ブロックの実行と変数の更新が行われます。
:<syntaxhighlight lang=
"use strict";
const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let i = 0, len = array.length; i < len; i++) {
}
</syntaxhighlight>
354 ⟶ 393行目:
ブロック文は文の特殊なケースで単文でももちろん有効です<ref>文 ⊇ ブロック文</ref>。
:<syntaxhighlight lang=
"use strict";
const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let i = 0, len = array.length; i < len; i++) console.log(array[i]);
</syntaxhighlight>
後置インクリメント演算子は変数の値を1増やし、増やす前の値を返すので、次のように書けます。
:<syntaxhighlight lang=
"use strict";
const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (let i = 0, len = array.length; i < len; console.log(array[i++]));
</syntaxhighlight>
このような書き方を好み人もいますが、文意を汲むなら...
:<syntaxhighlight lang=
"use strict";
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach((x) => console.log(x));
</syntaxhighlight>
のような、iterableオブジェクト<ref>この場合は Array オブジェクト</ref>の[[JavaScript/イテレーションメソッド|イテレーションメソッド]]を使うことも検討に値します。
=== for 文の構文 ===
:<syntaxhighlight lang=
for (
</syntaxhighlight>
*
* 式2が turuthy な間、以下を繰り返します
** 文 を実行します
385 ⟶ 427行目:
<!--スコープについて要加筆-->
=== for-in ===
for-in 文は、オブジェクトのプロパティのうちキーが文字列で列挙可能なもの全てに反復処理を行います。
;[https://paiza.io/projects/ZmkzUwnrzEgyff8eb60gEg?language=javascript 例]:<syntaxhighlight lang=
"use strict";
const obj = {
x: 2,
y: 3,
z: 5
};
for (const prop in obj) {
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
y: 3
z: 5
</syntaxhighlight>
=== for-of ===
for-of 文は、Iterableオブジェクト(たとえば String Array や NodeList)に対して、反復処理を行います<ref>ES2015で追加</ref>。
;[https://paiza.io/projects/GnxH5dTKhRA8Mcz24mIHTQ?language=javascript for-of]:<syntaxhighlight lang=
"use strict";
const ary = [..."XYZ"];
for (const el of ary) {
}
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
X
Y
Z
</syntaxhighlight>
Iterableでないオブジェクトが右の項に与えらてた場合、TypeError が throw されます。
;Objectはfor-of不可:<syntaxhighlight lang=
"use strict";
const obj = {
a: 0,
b: 1,
c: 2
};
for (const el of obj) {
}
</syntaxhighlight>
:Object はItableではないので
;実行時エラー:<syntaxhighlight lang=
/workspace/Main.js:8
for (const el of obj) {
^
TypeError: obj is not iterable
at Object.<anonymous> (/workspace/Main.js:8:18)
at Module._compile (node:internal/modules/cjs/loader:1126:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
at Module.load (node:internal/modules/cjs/loader:1004:32)
at Function.Module._load (node:internal/modules/cjs/loader:839:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
</syntaxhighlight>
:となります。
;[https://paiza.io/projects/8oFPy97Ozwg9nv4VPeWcTw?language=javascript for-ofとObjectの分割代入の併用]:<syntaxhighlight lang=
"use strict";
const AddrBook = [
{
name: "tom",
postnumber: "420-2410",
age: 18
},
{
name: "joe",
postnumber: "420-0824",
age: 17
}
];
for (const { name, age } of AddrBook) {
}
/** 同じコンセプトのArray::forEach */
AddrBook.forEach(({ name, age }) => console.log(`${name}: ${age}`));
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=
tom: 18
joe: 17
454 ⟶ 523行目:
</syntaxhighlight>
=== for await-of ===
for await-of 文は、非同期関数用の for-of です。
;[https://paiza.io/projects/nvHmwLQTDhA1cKqZGsKpTg?language=javascript 例]:<syntaxhighlight lang=
"use strict";
async function* asyncShift() {
for (let i = 1, len = 2 ** 16; i < len; yield (i <<= 3));
}
(async function () {
for await (const num of asyncShift()) {
console.log(num);
}
})();
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=text>
8
64
512
4096
32768
262144
</syntaxhighlight>
=== for each-in ===
for each-in 文はJavaScript 1.6で[[w:ECMAScript for XML|ECMAScript for XML]](E4X)のサポートの一環で導入されましたが、E4Xの廃止を受け非推奨を経て'''廃止'''されました。
下のプログラム例もモダンブラウザでは SyntaxError となります。[[#for … of|for … of]] 文を使うようにして下さい。<br>
JavaScript 1.6で追加されたfor each-in文はオブジェクトの値を順番に取り出して反復処理します。
:<syntaxhighlight lang=
var sales = <sales vendor="John">
<item type="peas" price="4" quantity="6"/>
496 ⟶ 567行目:
</SyntaxHighlight>
==
反復処理中に、反復を中断したり、「次の」反復にすぐに移りたい場合があります。
このようなときは、反復制御構文を使います。
=== break ===
'''[[w:break文|break文]]'''( ''break statement'' )はループまたはswitch文を途中で抜けます。
次のプログラムは''i''が5になった時点でfor文のループを抜けるので、0から4までの数字を表示します。
:<syntaxhighlight lang=
"use strict";
for (let i = 0; i < 10; i++) {
console.log(i);
}
</syntaxhighlight>
=== continue ===
'''[[w:continue文|continue文]]'''
次のプログラムは0から9までの数字のうち3の倍数だけ表示します。
:<syntaxhighlight lang=
"use strict";
for (let i = 0; i < 10; i++) {
console.log(i);
}
</syntaxhighlight>
=== ラベル ===
ラベルを使用すると深いループを一気に抜けることができます。
;ラベルの使用例:<syntaxhighlight lang=
"use strict";
let LOOP = "Global variable";
console.log([x, y]);
}
}
console.log(LOOP);
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=
[ 0, 0 ]
[ 0, 1 ]
552 ⟶ 627行目:
次は有効な JavaScript のコードです。
;URLが有効なJavaScript?:<syntaxhighlight lang=
"use strict";
https://ja.wikibooks.org/
for (let i = 0; i < 3; i++) {
567 ⟶ 644行目:
}}
=== その他の制御文 ===
<!-- 関数呼び出しと return文はここに含めるべき? -->
577 ⟶ 654行目:
with文の用途は、実際のコードを見ると良い。次の2つの関数は同じ意味です。
;[https://paiza.io/projects/tEknwwCpEg4jt7y9lcNPTw?language=javascript withの使用例]:<syntaxhighlight lang=
function math1() {
}
function math2() {
}
math1();
math2();
</syntaxhighlight>
;実行結果:<syntaxhighlight lang=
11
3.141592653589793
|