JavaScript関数における感嘆符(!)の意味
JavaScript関数における感嘆符(!)の意味
非nullアサーション演算子
TypeScriptで導入された非nullアサーション演算子(!)は、変数や関数の戻り値がnullまたはundefinedではないことを明示的に宣言するために使用します。
例:
function getName(user: User): string | undefined {
return user.name;
}
const name = getName(currentUser);
if (name === undefined) {
// エラーが発生する
} else {
// nameはnullまたはundefinedではないことが保証される
console.log(name.toUpperCase());
}
上記のコードでは、getName
関数はstring
またはundefined
を返す可能性があります。name
変数にgetName
関数の戻り値を代入すると、name
変数はstring
型またはundefined
型になる可能性があります。
そこで、name
変数に感嘆符(!)を付けてname!
と記述することで、name
変数はnull
またはundefined
ではないことを明示的に宣言できます。
ファクトリー関数
感嘆符(!)を関数名に付けることはあまり一般的ではありませんが、ファクトリー関数と呼ばれる特殊な関数を作成するために使用されることがあります。
ファクトリー関数は、常に新しいオブジェクトを生成して返す関数です。感嘆符(!)を付けることで、この関数が常に新しいオブジェクトを生成することを明示的に示すことができます。
function createUser(name: string, age: number): User {
return {
name,
age,
};
}
const user1 = createUser("John Doe", 30);
const user2 = createUser("Jane Doe", 25);
console.log(user1 === user2); // false
上記のコードでは、createUser
関数は常に新しいUser
オブジェクトを生成して返します。
このように、感嘆符(!)はJavaScript関数においてさまざまな意味を持ちます。それぞれの意味を理解して、適切に使用することが重要です。
補足
- TypeScriptでは、非nullアサーション演算子(!)はコンパイル時にのみ使用されます。実行時には、感嘆符(!)は削除されます。
- JavaScriptでは、感嘆符(!)は非nullアサーション演算子として正式にサポートされていません。しかし、多くの開発者が非公式にこの記法を使用しています。
function getName(user: User): string | undefined {
return user.name;
}
const name = getName(currentUser);
if (name === undefined) {
// エラーが発生する
} else {
// nameはnullまたはundefinedではないことが保証される
console.log(name.toUpperCase());
}
// 非nullアサーション演算子を使用
const name2 = getName(currentUser)!;
console.log(name2.toUpperCase()); // エラーが発生しない
function createUser(name: string, age: number): User {
return {
name,
age,
};
}
const user1 = createUser("John Doe", 30);
const user2 = createUser("Jane Doe", 25);
console.log(user1 === user2); // false
// ファクトリー関数
function createUser!(name: string, age: number): User {
return {
name,
age,
};
}
const user3 = createUser!("John Doe", 30);
const user4 = createUser!("Jane Doe", 25);
console.log(user3 === user4); // false
補足
- 上記のコードはあくまでもサンプルです。実際のコードでは、必要に応じて修正してください。
- ファクトリー関数は、常に新しいオブジェクトを生成する必要がある場合にのみ使用してください。
非nullアサーション演算子(!)の代替方法
オプショナルチェイニング演算子(?.)を使用すると、nullまたはundefinedの可能性があるプロパティに安全にアクセスすることができます。
function getName(user: User): string | undefined {
return user.name;
}
const name = getName(currentUser)?.toUpperCase();
if (name === undefined) {
// nameはnullまたはundefined
} else {
// nameはnullまたはundefinedではない
console.log(name);
}
nullチェック演算子(??)を使用すると、nullまたはundefinedの場合にデフォルト値を返すことができます。
function getName(user: User): string | undefined {
return user.name;
}
const name = getName(currentUser) ?? "Unknown";
console.log(name); // "John Doe" または "Unknown"
型ガードを使用すると、変数の型を検査することができます。
function getName(user: User): string | undefined {
return user.name;
}
const name = getName(currentUser);
if (name !== undefined) {
// nameはnullまたはundefinedではない
console.log(name.toUpperCase());
}
ファクトリー関数の代わりに以下の方法を使用することができます。
コンストラクタ関数を使用すると、新しいオブジェクトを生成することができます。
class User {
constructor(public name: string, public age: number) {}
}
const user1 = new User("John Doe", 30);
const user2 = new User("Jane Doe", 25);
console.log(user1 === user2); // false
const user1 = {
name: "John Doe",
age: 30,
};
const user2 = {
name: "Jane Doe",
age: 25,
};
console.log(user1 === user2); // false
- 型ガードは、変数の型を検査したい場合に使用します。
それぞれの方法の長所と短所を理解して、適切な方法を選択してください。
javascript function