3.6 現代の JavaScript で使う演算子と構文

ここでは、スコープの学習と並行して押さえておきたい、現代の JavaScript 開発で頻繁に使われる演算子と構文を紹介します

3.6.1 厳密な等価演算子(=== と !==)

JavaScript で値を比較する際、==(等価演算子)と ===(厳密等価演算子)という 2 種類の比較演算子があります。

== は値だけを比較し、型が違っても自動的に型変換を行ってから比較します。
一方、=== は値だけでなく型も比較するため、型が違えば必ず false を返します。

現代の JavaScript 開発では、予期しない動作を防ぐため、=== と !== を使うことが強く推奨されています。

ソースフォルダ:public/ch03

ファイル名:strict-equality.js

➢ strict-equality.html

前項で作った ch03/block-scope.html をコピーし、ch03 にペーストしてください。その際に、ファイル名を strict-equality.html に変更します。ファイル内の block-scope.html や block-scope.jsの記述も、strict-equality.html や strict-equality.js に修正します。

➢ strict-equality.js

// strict-equality.js

// 1. 数値の 0 と 文字列の "0" を用意します
let num = 0;
let str = "0";

// 2. == で比較(型変換が起こる)
let result1 = (num == str);
alert("num == str の結果: " + result1); // true(型変換後、値が同じ)

// 3. === で比較(型も比較する)
let result2 = (num === str);
alert("num === str の結果: " + result2); // false(型が違う)

// 4. 型の確認
alert("num の型: " + typeof num + "\nstr の型: " + typeof str);

実行結果

解説

まず 4 行目と 5 行目で、数値の 0 と文字列の “0” という、型の異なる 2 つの変数を定義しています。

4: let num = 0;
5: let str = "0";

8 行目では、==(等価演算子)を使って比較しています。
この演算子は、比較の前に自動的に型変換を行います。文字列の “0” が数値の 0 に変換されてから比較されるため、結果は true になります。

8: let result1 = (num == str);
9: alert("num == str の結果: " + result1); // true

12 行目では、===(厳密等価演算子)を使って比較しています。
この演算子は、型変換を行わず、値と型の両方が一致するかをチェックします。num は数値型、str は文字列型なので、型が異なるため結果は false になります。

12: let result2 = (num === str);
13: alert("num === str の結果: " + result2); // false

16 行目では、typeof 演算子を使って、それぞれの変数の型を確認しています。
num は number(数値型)、str は string(文字列型)であることが分かります。

16: alert("num の型: " + typeof num + "¥nstr の型: " + typeof str);

なぜ ===(厳密等価演算子)を使うべきか

==(等価演算子)による型変換は、時に予想外の結果を招きます。

console.log(0 == ""); // true(空文字列が 0 に変換される)
console.log(0 == false); // true(false が 0 に変換される)
console.log(null == undefined); // true(特殊な挙動)

実務では、このような暗黙的な型変換が原因でバグが発生することがあります。
そのため、現代の JavaScript 開発では、意図しない型変換を防ぐために === と !== を使うことが標準となっています。

typeof 演算子

=== での比較が「型も含めて比較する」ものであるのに対し、typeof は変数や値の型そのものを文字列で返す演算子です。

typeof 42 // "number"
typeof "hello" // "string"
typeof true // "boolean"
typeof undefined // "undefined"
typeof null // "object" ← 歴史的な仕様バグ。null は object ではないが注意が必要
typeof {} // "object"
typeof [] // "object" ← 配列も object になる
typeof function(){} // "function"

=== と組み合わせることで、型を確認してから処理を分岐させるコードが書けます。

function printLength(value) {
    if (typeof value === "string") {
        alert("文字数: " + value.length);
    } else if (typeof value === "number") {
        alert("数値です: " + value);
    } else {
        alert("その他の型: " + typeof value);
    }
}

注意点として、typeof null が “object” を返すのは JavaScript の歴史的な仕様バグです。null チェックにはtypeof ではなく === null を使います。

null と undefined

JavaScript には「値がない」状態を表す特別な値が 2 つあります。Java には null しかありませんが、JavaScript では区別して使います。

undefined が自動的にセットされる代表的なケースを押さえておきましょう。

// 宣言したが値を代入していない変数
let name;
console.log(name); // undefined

一方 null は、開発者が「ここは意図的に空にしている」と明示したい場合に使います。

// データをまだ格納していない状態を表す
let userData = null;

以下の方法で null または undefined であるかをチェックすることができます。

// undefined のチェック
if (typeof value === "undefined") { ... } // 推奨
if (value === undefined) { ... } // こちらも可

// null のチェック
if (value === null) { ... } // ===を使う(==は undefined も一致してしまう)

// null・undefined の両方をまとめてチェックしたい場合のみ == が有効
if (value == null) { ... } // null と undefined の両方にマッチする(意図的な場合のみ)

先ほどのコード例にあった null == undefined が true になる理由はここにあります。== は null とundefined を同一視する特別な挙動を持っています。これが「特殊な挙動」と注釈されていた理由です。通常のチェックでは === を使い、null と undefined は別々に扱うことが推奨されています。

3.6.2 テンプレートリテラル

これまでの章では、変数と文字列を + で繋げる書き方を使ってきました。

const name = "Alice";
alert("こんにちは、" + name + "さん!");

ES6 以降の現代的な JavaScript では、より短く読みやすく書ける テンプレートリテラル という記法が用意されています。

書式:テンプレートリテラル
`文字列の中に ${変数や式} を埋め込める`

” や ‘ の代わりに `(バッククォート:Shift + @ キー)で囲みます。

const name = "Alice";
alert(`こんにちは、${name}さん!`); // こんにちは、Alice さん!

テンプレートリテラルの特徴は 2 つあります。

1. ${ } の中に変数や式を直接埋め込める

${ } の中には変数だけでなく、計算式や関数の呼び出し結果も書けます。

const price = 1000;
const quantity = 3;
alert(`合計金額: ${price * quantity}円`); // 合計金額: 3000 円
2. 改行をそのまま書ける

” や ‘ で囲んだ文字列では改行を ¥n で表現する必要がありましたが、テンプレートリテラルでは実際の改行をそのまま含めることができます。

// 従来の書き方
alert("1 行目¥n2 行目¥n3 行目");

// テンプレートリテラル
alert(`1 行目
2 行目
3 行目`);

ポイント

  • `(バッククォート)は ” や ‘ とは別の文字。混在させないよう注意する。
  • ${ } の外側に書いた文字はそのまま出力される。
  • ${ } の中を誤って文字列全体で括ってしまうと動作しない。

この章で学んだ let や const で宣言した変数は、以降のすべての章で ${ } に埋め込む形で頻繁に登場します。
使いながら慣れていきましょう。