if文、do - while文、for文がある。中身の文が一つだけのときは、C/C++と同様、{ } を省略できる。 { } を省略せずに書いているサイト・サンプルが非常に多い。
while文do - whileもC/C++と同じ。
continue, break文もある。
try文JavaScriptには例外機構もある。
TryStatement :
try Block Catch
try Block Finally
try Block Catch Finally
Catch :
catch ( Identifier ) Block
Finally :
finally Block
catch は, ただ一つの Identifier しか引数に取ることができない。
印象がなかったが, 1999年の 3rd edition から使えるようになっていたらしい。
関数を定義するには, function にて次のように書く。
function 関数名 ( 仮引数リスト ) { 本体 }
function ( 仮引数リスト ) { 本体 }
関数式は関数オブジェクトを生成し、そのオブジェクトを返す。このオブジェクトを変数に代入することもできる (first-class object; 第一級のオブジェクト)。
文法では、関数式にも関数名を指定できるが、単に無視される。
JavaScript の関数宣言/定義では、変数や戻り値の型を宣言できない。実行時に自分でテストするしかない。
関数は, 常に戻り値を返す。明示的に return しなかった場合, 暗黙に undefined が戻り値になる。最後に評価した式の値ではない。これはあまり上手くない仕様だが、今更変えられない。
型宣言がないので、return 忘れなどを検出できない。
JavaScriptのメソッドは, クラスに所属しているわけではなく, ただの関数。
ES2015 で「アロー関数」が導入された。関数式をものすごく短く書くことができる。
[2020-12] ES2020 で追加された ?., ??
演算子の優先順位と結合は次のとおり。評価 (実行) 順とは異なる。
| 優先 順位 | 演算子 | 説明 | 結合 |
|---|---|---|---|
| 1 | . | メンバアクセス | 左 |
...[ ... ] | メンバアクセス | ||
... ( ... ) | 関数呼び出し | ||
?. | Optional chaining [ES2020で導入]. 左辺が nullish (null or undefined) でないときメンバアクセス. 右辺は短絡評価。
| ||
| 2 | new | オブジェクトの生成 | 右 |
| 3 | ++ -- | 後置インクリメント・デクリメント | なし |
| 4 | delete | プロパティの削除 | 右 |
void typeof | |||
++ -- | 前置インクリメント・デクリメント | ||
+ - | 単項: 正号, 負号 | ||
~ ! | ビット否定, 論理否定 | ||
| 5 | ** | 累乗 (べき乗) [ES2016 で導入] | 右 |
| 6 | * / % | 乗算, 除算, 剰余. 剰余は実数で計算. | 左 |
| 7 | + - | 二項演算子: 加算, 減算 | 左 |
| 8 | << >> >>> | ビットシフト. >>> は符号なし右シフト。 | 左 |
| 9 | < > <= >= | 比較 | 左 |
instanceof in
| |||
| 10 | == != === !== | 比較. 型に厳しいかどうか | 左 |
| 11 | & | ビット論理積 (and) | 左 |
| 12 | ^ | ビット排他的論理和 (xor) | 左 |
| 13 | | | ビット論理和 (or) | 左 |
| 14 | && | 論理積 (and). 左辺値か右辺値を返す. 短絡評価する. | 左 |
| 15 | || | 論理和 (or). 左辺値か右辺値を返す. 短絡評価する. | 左 |
?? | Null合体 (Nullish coalescing) [ES2020で導入]. 偽ではなく null or undefined で判定。論理和 (or) と並べて書けない (SyntaxError).
| ||
| 16 | ? : | 3項演算子. 第2項と第3項は短絡評価する. | 右 |
| 17 | =**= *= /= %= += -= <<= >>= >>>= &= ^= |= | 代入. | 右 |
| 18 | , | 順列 | 左 |
大なりイコールは >= のみ。=> はアロー関数 (Arrow function; ES2015 で導入) になる。
[2020-12] &&=, ||= は提案中。まだ標準ではない。
短絡評価 (short-circuit evaluation) は遅延評価と同じ。評価を省略できる式は実行されない。
== と ===変わっているのは、厳密な比較演算子「===」と「!==」。== と異なり, 暗黙の型変換を行わない。現代では, == と != は使うべきでなく, 常に === と !== を使うべき、となっている。
switch文でも, 比較には === が用いられる。
いろいろな値同士を比較した結果。意外なことが多いが、特に注意を要するところは赤字にした。オブジェクト同士の比較には、比較演算子は一切使えない。ひどい。
加えて、Object.is() による比較も、わずかに異なる。この、わずかに、というのが実に不味い。
| x | y | x == y
| x === y
| Object.is()
| |
|---|---|---|---|---|---|
| '5' | 5 | true | false | false | == では型変換される
|
| 5.0 | 5 | true | true | true | JavaScript の Number型は実数
|
| +0 | -0 | true | true | false | Object.is() だけが +0 と -0 を区別する。
|
| 0 | NaN | false | false | false | 0 と NaN はいずれも偽だが、等しくない.
|
NaN | NaN | false | false | true | NaN は NaN 自身とも等しくない! |
Infinity | Infinity | true | true | true | 無限大同士は等しい. |
| 1 | 1n | true | false | false | 整数型 BigInt 値と数値は === だと等しくない!
|
| 'あい' | 'あい' | true | true | true | 文字列プリミティブは、内容で比較される. |
| 'あい' | new String('あい') | true | false | false | Stringオブジェクトだと不一致! プリミティブをnew してはならない。
|
| 1 | true | true | false | false | true の数値表現は1だが, === だと型が違うので false.
|
| 2 | true | false | false | false | 真の値一般と等しい訳ではない. つまり Boolean 型に変換されてから比較されるわけではない。 |
false | false | true | true | true | false 同士は等しい. |
| 0 | false | true | false | false | false の数値表現は 0 |
NaN | false | false | false | false | falseも, 偽の値一般と等しい訳ではない。 |
null | null | true | true | true | |
null | 0 | false | false | false | null と 0 も異なる. |
undefined | 0 | false | false | false | 同様に, undefined と 0も異なる.
|
undefined | undefined | true | true | true | |
null | undefined | true | false | false | === の場合, null と undefined も異なる.
|
Symbol("foo") | "foo" | false | false | false | シンボルは文字列と別物。 |
| [1,2,3] | [1,2,3] | false | false | false | オブジェクトは, 内容ではなく, 同じ参照かどうかで判定! |
| [] | [] | false | false | false | たとえ空配列でも同様。 |
| {} | {} | false | false | false | オブジェクトは、中身の値ではなく、同じ参照かどうか。 |
ES5 までは, 変数のスコープは、大域スコープと関数スコープしかない。ループのブロックでは新しいスコープは導入されない。
関数定義のなかでのvar宣言で,「関数スコープ」の変数を宣言できる。var宣言は、関数ブロックの先頭で実行されたかのように扱われる。大域変数はシャドーイング (shadowing) される。
ES2015 (ES6) で, let と const が導入された.
let は, 変数の再宣言は禁止されるが再代入できる変数。const は変数の再宣言も再代入もできない。スコープは, if 文や for 文などのブロック内で宣言されれば, そのブロック内になる。
var は、変数の再宣言も許し、スコープは関数になる。
現代では, var はほぼほぼ使われない。let を使う機会も, for-of文ぐらいで、ほとんどない。基本的にいつでも const でよい。
代入「=」は、変数が指すオブジェクトのコピーではなく、変数が指すオブジェクトの切り替えになる。複数の変数からひとつのオブジェクトを参照できる。いまどきのプログラミング言語と同じ。
変数の値への束縛は、関数の実行時に行われる。次の例は、関数g()の定義のときに変数xが束縛されるわけではないことを示す。だから、クロージャではない。
Internet ExplorerとFirefox / SeaMonkeyでは、実装しているオブジェクト、メソッドにだいぶ違いがある。portableなプログラムを書こうと思うなら、これらの差異を吸収してくれるライブラリを使うのがいい。以下では、共通するオブジェクト、メソッドについて解説する。
プロパティ
メソッド
Symbolオブジェクト (ES2015で導入)Error オブジェクト