89
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【JavaScript】Null合体演算子と(??)とオプショナルチェイニング演算子(?.)

Last updated at Posted at 2020-07-12

はじめに

JavaScriptの言語使用は、Ecma Internationalによって定められており2015年からはECMAScriptとして毎年改定されています。

ECMAScript2020の仕様としてNull合体演算子(??)とオプショナルチェイニング演算子(?.)が追加されました。(その他にもいくつかの機能が追加されています。詳細はこちらのリンクにまとめられています。

Null合体演算子とオプショナルチェイニング演算子は、どちらもnullableな変数に安全にアクセスするという似たような目的を持っており、かつググラビリティが低いという特徴を持っています。

現時点(2020年)で最新の仕様であり、あまり現場で見かけることがないかもしれませんが、この2つの演算子の特徴を見ていきましょう。

Null合体演算子

Null合体演算子は、演算子の一種で左辺がnullまたはundefinedのときに右辺の値を返し、それ以外のときには左辺を返します。
C#、Swift、PHPなどにも採用されているため見覚えがある人も多いかもしれません。

構文

A ?? B
let text;

const title = text ?? "タイトル";
console.log(title); // タイトル

これは以下の構文と同意義で、シンタックスシュガーといえます。

let text;

const title = text != null ? text : "タイトル";
console.log(title); // タイトル

OR(||)演算子との違い

Null合体演算子導入前までは、同じような機能を提供するために、OR(||)演算子が使われていました。

let text;

const title = text || "タイトル";
console.log(title); // タイトル

この結果を見ると、Null合体演算子とOR演算子どちらを使っても変わらないように思わます。

しかし、OR演算子はnullundefinedに限らずfalsyな値0, '', NaN, null, undefinedのときに左辺の値を返すという特徴があります。

これは、例えば0をを正しい値として扱いたいときに思わぬ結果を返す可能性があります。

const value = 0;

const a = value ?? "記録がありません。";
const b = value || "記録がありません。";

console.log(a); // 0
console.log(b); // 記録がありません。

短絡評価

Null合体演算子は、AND演算子やOR演算子のように短絡評価されます。
右辺の値がnullまたはundefinedでないことが証明されたとき、右辺の値は評価されません。

const a = "a" ?? console.log("a");
const b = null ?? console.log("b"); // b

AND演算子やOR演算子と同時に使えない

Null合体演算子を、AND演算子やOR演算子と直接同時に使おうとするとsyntax errorが発生します。

const a = 0 || null ?? 'a'
const b = 1 && null ?? 'b'

// error: Uncaught SyntaxError: Unexpected token '??'
// const a = 0 || null ?? 'a'

Null合体演算子をAND演算子やOR演算子と使用したいときには、カッコをつけて明示的に優先順位をつける必要があります。

const a = (0 || null) ?? "a";
const b = (1 && null) ?? "b";

console.log(a); // a
console.log(b); // b

使用例

Null合体演算子は、nullableな要素を使用する際に初期値を代入したいときに役に立ちます。

例えば、次の例はクエリパラメータにusernameが存在すればそれをページのタイトルとし、存在しないときには初期値を代入します。

const params = (new URL(document.location)).searchParams;
document.title = params.get('username') ?? 'Default Title';

オプショナルチェイニング演算子

オプショナルチェイニング演算子(?.)は、ググりづらい上に名前まで長くて覚えづらいという厄介な演算子ですが(?)なかなか役にたちます。

オプショナルチェイニング演算子は、nullableなオブジェクトに対して安全にアクセスするための演算子です。これは、プロパティにアクセスするときに.の代わりに?.を使用して、オブジェクトがnullまたはundefiendだった場合、実行時エラーを吐く代わりにundefinedを返します。

構文

obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)
let user;

console.log(user.name);
// error: Uncaught SyntaxError: Unexpected token '?'
// console.log(user?.name)

console.log(user?.name);
// undefined

オプショナルチェイニング演算子をネストした演算子に使う

オプショナルチェイニング演算子は、何個でも使用できるため次のようにネストしたプロパティに対しても使用することができます。

const obj {
  first: {
    second: {
      third: 'hey!'
    }
  }
}

obj?.first?.secont?.third

オプショナルチェイニング演算子を使用した関数呼び出し

オプショナルチェイニング演算子は安全に関数を呼び出すために使用することができます。
関数呼び出しには次のような構文に従います。

obj.someFunction?.() 

しかし、この構文が有効に働くのはsomeFunction()が存在したいときだけです。以下の例のように、存在はするがメソッドではないプロパティに対して使用すると例外をスローします。

const obj = {
  someFunction: "1",
};

obj.someFunction?.();
// error: Uncaught TypeError: obj.someFunction is not a function
// obj.someFunction?.();

ブラケット表記法に使用する

const obj = { 
   first: 1,
   second: 2
}

const page = 'first'

const content = obj?.[page]

配列の要素にアクセスするときに使用する

const array = ["first", "second"];
const notArray = "1";

console.log(array?.[0]); // first
console.log(array?.[3]); // undefined
console.log(notArray?.[0]); // undefined
console.log(notArray?.[1]); // undefined

使用例

オプショナルチェイニング演算子は、APIから取得した要素や、DOMから取得した要素など、nullundefinedで返されるオブジェクトにアクセスするときに役に立ちます。

例えば、次の例はUser型のオブジェクトの配列からidをもとに特定のユーザーを見つけ出し名前を表示しようとしますがfind()メソッドはundefinedを返す可能性があります。

if (user == null)のように存在確認してからプロパティにアクセスすることもできますが、オプショナルチェイニング演算子を使えば簡潔に記述することができます。

const users = [
  {
    id: 1,
    name: "Aron",
  },
  {
    id: 2,
    name: "Abel",
  },
  {
    id: 3,
    name: "Michael",
  },
];

const user = users.find((user) => user.id === 4);
console.log(user?.name);

おわりに

WikipediaのNull合体演算子のJavaScriptの項目誰か更新しといてください。

2021/06/17 更新されてました。

89
65
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
89
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?