if文、do - while文、for文がある。中身の文が一つだけのときは、C/C++と同様、{ } を省略できる。 { } を省略せずに書いているサイト・サンプルが非常に多い。
while
文do - whileもC/C++と同じ。
continue
, break
文もある。
try
文JavaScriptには例外機構もある。
TryStatement :try
Block Catchtry
Block Finallytry
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
オブジェクト