目次
Null合体演算子 ??
|| との違い
前の章で || を「デフォルト値」に使えると説明しました。
const input = ""; // ユーザー入力(今は空文字)
const name = input || "名無し";
console.log(name); // "名無し"でも、「空文字 "" 自体を有効な値として扱いたい」場面では困ります。
ここで登場するのが Null合体演算子 ?? です。
const input = "";
const name = input ?? "名無し";
console.log(name); // ""(空文字がそのまま使われる)挙動の違い:
A || B
→ A が Falsy なら B、そうでなければ AA ?? B
→ A が null または undefined なら B、そうでなければ A
つまり、?? は「null / undefined のときだけデフォルト値」という意味になります。
具体的な比較
console.log(0 || 42); // 42(0 は Falsy)
console.log(0 ?? 42); // 0 (0 は null/undefined ではない)
console.log("" || "default"); // "default"(空文字は Falsy)
console.log("" ?? "default"); // ""(空文字は null/undefined ではない)
console.log(null || "default"); // "default"
console.log(null ?? "default"); // "default"
console.log(undefined || "default"); // "default"
console.log(undefined ?? "default"); // "default"実務的な指針:
- 「未設定(null/undefined)のときだけ デフォルトを使いたい」 →
?? - 「0 や空文字も“ないもの”として扱いたい」 →
||
オプショナルチェイニング ?.
undefined / null によるエラー
よくあるエラー:
const user = null;
// console.log(user.name); // TypeError: Cannot read properties of nulluser が null や undefined のときにプロパティアクセスするとエラーになります。
それを避けるために、今まではこんな書き方をしていました。
const userName = user && user.name ? user.name : "名無し";?. で安全にアクセス
オプショナルチェイニング ?. を使うと:
const user = null;
const name = user?.name ?? "名無し";
console.log(name); // "名無し"user?.name の挙動:
userがnullorundefinedのとき
→user?.nameは エラーではなくundefinedを返す- それ以外(オブジェクトが入っている)とき
→ 通常通りuser.nameを評価
組み合わせると:
const name = user?.name ?? "名無し";意味:
「user があって name が取れればその値、取れなければ '名無し'」
ネストにも使える
const user = {
profile: {
name: "Taro",
},
};
console.log(user.profile.name); // "Taro"
console.log(user.profile?.name); // "Taro"
console.log(user.address?.city); // undefined(エラーにならない)
console.log(user.address?.city ?? "不明"); // "不明"「深くネストしたオブジェクトの一部が無いかもしれない」
という場面で、?. は非常に便利です。
論理代入演算子 &&=, ||=, ??=
「既存の値」に基づいて、「条件付きで代入する」ためのショートカットです。
||=:Falsy のときだけ代入
let name = ""; // まだ未設定という扱いにしたい
name ||= "名無し";
console.log(name); // "名無し"これは、次と同じ意味です:
let name = "";
if (!name) {
name = "名無し";
}- 左辺が Falsy なら右辺を代入
- それ以外は何もしない
&&=:Truthy のときだけ代入
let isEnabled = true;
let flag = true;
flag &&= isEnabled;
console.log(flag); // true(両方 true)
flag = false;
flag &&= isEnabled;
console.log(flag); // false(最初が Falsy なので代入されない)これは、次と同じ意味です:
if (flag) {
flag = isEnabled;
}??=:null/undefined のときだけ代入
?? と同じく、「null/undefined のときだけ」というバージョンです。
let title = null;
title ??= "デフォルトタイトル";
console.log(title); // "デフォルトタイトル"
let count = 0;
count ??= 10;
console.log(count); // 0(0はnull/undefinedではないのでそのまま)これは、次と同じ意味です:
if (title === null || title === undefined) {
title = "デフォルトタイトル";
}実務的には:
- 「未設定(null/undefined)のときだけ初期値を入れたい」 →
??= - 「とにかく Falsy のときだけ初期値」 →
||=
(ただし 0 や “” も上書きされる)
分割代入(destructuring)
配列の分割代入
従来:
const arr = [1, 2, 3];
const a = arr[0];
const b = arr[1];
const c = arr[2];分割代入:
const arr = [1, 2, 3];
const [a, b, c] = arr;
console.log(a, b, c); // 1 2 3飛ばしたり、デフォルト値もOK:
const arr = [10];
const [x, y = 20] = arr;
console.log(x, y); // 10 20
const [, second] = [100, 200, 300];
console.log(second); // 200オブジェクトの分割代入
従来:
const user = { name: "Taro", age: 20 };
const name = user.name;
const age = user.age;分割代入:
const user = { name: "Taro", age: 20 };
const { name, age } = user;
console.log(name, age); // "Taro" 20別名をつけることもできます:
const user = { name: "Taro", age: 20 };
const { name: userName, age: userAge } = user;
console.log(userName, userAge); // "Taro" 20デフォルト値:
const user = { name: "Taro" };
const { name, age = 18 } = user;
console.log(name, age); // "Taro" 18関数引数と組み合わせる
よくあるパターン:
function printUser({ name, age }) {
console.log(`名前:${name}, 年齢:${age}`);
}
const user = { name: "Hanako", age: 25 };
printUser(user); // 名前:Hanako, 年齢:25「引数として受け取ったオブジェクトから、一部のプロパティだけ使う」という場面でとても便利です。
スプレッド構文 …(展開)
配列のコピー・結合
const arr1 = [1, 2];
const arr2 = [3, 4];
const arr3 = [...arr1, ...arr2];
console.log(arr3); // [1, 2, 3, 4]浅いコピーにも使えます:
const original = [1, 2, 3];
const copy = [...original];
copy.push(4);
console.log(original); // [1, 2, 3]
console.log(copy); // [1, 2, 3, 4]オブジェクトのコピー・マージ
const base = { a: 1, b: 2 };
const extra = { b: 99, c: 3 };
const merged = { ...base, ...extra };
console.log(merged); // { a:1, b:99, c:3 }- 右側にあるプロパティが同じキーを上書きする
...を使うことで「浅いコピー」を簡単に書ける
const と組み合わせると、「参照ではなく中身のコピー」を作れる。
テンプレートリテラル `…`
文字列連結より見やすい書き方
従来:
const name = "Taro";
const score = 90;
const message = "名前:" + name + ", 点数:" + score;
console.log(message);テンプレートリテラル:
const name = "Taro";
const score = 90;
const message = `名前:${name}, 点数:${score}`;
console.log(message);`...`(バッククォート)で囲む${ ... }の中に式を書ける(変数だけでなく計算もOK)
const a = 10;
const b = 20;
console.log(`a + b = ${a + b}`); // "a + b = 30"複数行文字列がそのまま書ける
従来(普通の文字列):
const text = "1行目\n2行目\n3行目";テンプレートリテラル:
const text = `
1行目
2行目
3行目
`;
console.log(text);- 改行やインデントも含めて、そのまま文字列になる
- ログメッセージや HTML を組み立てるときにかなり便利
コメント