概要: このチュートリアルでは、連結されたオブジェクトのプロパティにアクセスする方法を簡素化するオプショナルチェイニング演算子 (?.) について学習します。
JavaScript オプショナルチェイニング演算子の概要
オプショナルチェイニング演算子 (?.) は、一連のオブジェクトのネストされたプロパティにアクセスするためのショートカットのようなものです。チェーンの各ステップが空(null または undefined)かどうかを確認する代わりに、演算子 ?. を使用して目的のプロパティに直接アクセスできます。
チェーンの一部が空の場合、オプショナルチェイニング演算子 (?.) はそこで停止し、結果として undefined を返します。チェーンの各ステップに対して追加のチェックを記述する手間を省くことができます。
user オブジェクトを返す関数があるとします。
function getUser(id) {
if(id <= 0) {
return null;
}
// get the user from database
// and return null if id does not exist
// ...
// if user was found, return the user
return {
id: id,
username: 'admin',
profile: {
avatar: '/avatar.png',
language: 'English'
}
}
}Code language: JavaScript (javascript)以下は、getUser() 関数を使用してユーザープロファイルにアクセスする例です。
let user = getUser(1);
let profile = user.profile;Code language: JavaScript (javascript)ただし、0 以下の id を渡した場合、またはデータベースに id が存在しない場合、getUser() 関数は null を返します。
したがって、avatar プロパティにアクセスする前に、論理演算子 AND を使用して user が null でないことを確認する必要があります。
let user = getUser(2);
let profile = user && user.profile;Code language: JavaScript (javascript)この例では、user.profile プロパティの値にアクセスする前に、user が null または undefined でないことを確認しています。ユーザーを最初に確認せずに user.profile に直接アクセスすると発生するエラーを防ぎます。
ES2020 では、疑問符とドットで表されるオプショナルチェイニング演算子が導入されました。
?.Code language: JavaScript (javascript)オプショナルチェイニング演算子を使用してオブジェクトのプロパティにアクセスするには、次のいずれかを使用します。
objectName ?. propertyName
objectName ?. [expression]Code language: JavaScript (javascript)オプショナルチェイニング演算子は、user.profile にアクセスする前に、user が null または undefined でないことを暗黙的にチェックします。
let user = getUser(2);
let profile = user ?. profile;Code language: JavaScript (javascript)この例では、user が null または undefined の場合、オプショナルチェイニング演算子 (?.) はすぐに undefined を返します。
技術的には、これは以下と同等です。
let user = getUser(2);
let profile = (user !== null || user !== undefined)
? user.profile
: undefined;
Code language: JavaScript (javascript)オプショナルチェイニング演算子の積み重ね
getUser() によって返された user オブジェクトに profile プロパティがない場合、user.profile を確認せずに avatar にアクセスしようとするとエラーが発生します。
エラーを回避するには、次のようにオプショナルチェイニング演算子を複数回使用できます。
let user = getUser(-1);
let avatar = user ?. profile ?. avatar;Code language: JavaScript (javascript)この場合、avatar は undefined です。
Null 合体演算子との組み合わせ
user にデフォルトのプロファイルを割り当てたい場合は、次のようにオプショナルチェイニング演算子 (?.) と Null 合体演算子 (??) を組み合わせることができます。
let defaultProfile = { default: '/default.png', language: 'English'};
let user = getUser(2);
let profile = user ?. profile ?? defaultProfile;Code language: JavaScript (javascript)この例では、user.profile が null または undefined の場合、Null 合体演算子により、profile は defaultProfile になります。
関数呼び出しでオプショナルチェイニング演算子を使用する
次のようなファイル API があるとします。
let file = {
read() {
return 'file content';
},
write(content) {
console.log(`Writing ${content} to file...`);
return true;
}
};Code language: JavaScript (javascript)この例では、file オブジェクトの read() メソッドを呼び出します。
let data = file.read();
console.log(data);Code language: JavaScript (javascript)file オブジェクトに存在しないメソッドを呼び出すと、TypeError が発生します。
let compressedData = file.compress();Code language: JavaScript (javascript)エラー
Uncaught TypeError: file.compress is not a functionCode language: JavaScript (javascript)ただし、メソッド呼び出しでオプショナルチェイニング演算子を使用すると、式はエラーをスローする代わりに undefined を返します。
let compressedData = file.compress?.();Code language: JavaScript (javascript)compressedData は jetzt undefined です。
これは、特定のブラウザやデバイスなど、何らかの理由でメソッドが使用できない場合に API を使用する場合に役立ちます。
関數またはメソッド呼び出しでオプショナルチェイニング演算子を使用する構文を以下に示します。
functionName ?. (args)Code language: JavaScript (javascript)オプショナルチェイニング演算子 (?.) は、オプションの コールバック を持つ関数がある場合にも役立ちます。
function getUser(id, callback) {
// get user
// ...
let user = {
id: id,
username: 'admin'
};
// test if the callback exists
if ( callback ) {
callback(user);
}
return user;
}Code language: JavaScript (javascript)オプショナルチェイニング演算子を使用することにより、コールバックが存在するかどうかテストをスキップできます。
function getUser(id, callback) {
// get user
// ...
let user = {
id: id,
username: 'admin'
};
// test if the callback exists
callback ?. (user);
return user;
}Code language: JavaScript (javascript)まとめ
- オプショナルチェイニング演算子 (
?.) は、nullまたはundefinedオブジェクトのプロパティにアクセスしようとすると、エラーをスローする代わりにundefinedを返します:obj ?. property. - オプショナルチェイニング演算子 (
?.) と Null 合体演算子 (??) を組み合わせてデフォルト値を割り当てます。 functionName ?. (args)を使用して、呼び出す前にfunctionNameがundefinedまたはnullでないことを明示的にチェックすることを回避します。