TypeScript - nullとundefinedの違い

こんにちは、将来のプログラマーさんたち!今日は、初心者の方々がよく混乱する興味深い話題に取り組んでみましょう:TypeScriptにおけるnullundefinedの違いです。もし少し不安感じていれば、心配しないでください - 私も最初にこれらの概念に遭遇したときは、頭を悩まされたことを覚えています!しかし、このレッスンの終わりまでに、この二つの特別な値を区別するプロになるでしょう。それでは、始めましょう!

TypeScript - null vs. undefined

nullとは?

TypeScript(およびJavaScript)では、nullは意図的なオブジェクト値の不在を表す特別な値です。まるで、「ここに何かがあるはずだが、今は何もない」と言っているようなものです。

以下の例を見て、これをより理解しやすくしましょう:

let myPet: string | null = null;
console.log(myPet); // 出力: null

// コードの後半で...
myPet = "Fluffy";
console.log(myPet); // 出力: Fluffy

この例では、myPetという変数を文字列またはnullとして宣言しています。最初はnullに設定し、ペットがいないことを示しています。後でペットを手に入れたときには、「Fluffy」という名前をmyPetに割り当てます。

もう一つの例を見てみましょう:

function findUser(id: number): { name: string } | null {
// データベースを検索していると仮定します
if (id === 1) {
return { name: "Alice" };
} else {
return null;
}
}

let user = findUser(1);
console.log(user); // 出力: { name: "Alice" }

user = findUser(2);
console.log(user); // 出力: null

この場合、findUser関数はユーザーオブジェクトを返すか、ユーザーが見つからない場合にnullを返します。これはプログラミングでよくあるパターンです - nullを使って検索や操作が結果を yield しなかったことを示します。

undefinedとは?

では、undefinedについて話しましょう。この特別な値は、宣言されたがまだ値が割り当てられていない変数を表します。まるで、空の箱があるが、中には何もないようなものです。

以下の例でundefinedを説明します:

let myName: string;
console.log(myName); // 出力: undefined

// コードの後半で...
myName = "John";
console.log(myName); // 出力: John

function greet(name?: string) {
console.log(name);
}

greet(); // 出力: undefined
greet("Alice"); // 出力: Alice

最初の部分では、myNameを宣言しますが値を割り当てません。TypeScriptは自動的にundefinedという値を割り当てます。後で値を割り当てると、もはやundefinedではありません。

greet関数では、オプションのパラメータを使っています。関数を引数なしで呼び出すと、nameパラメータはundefinedになります。

以下のもう一つのシナリオでは、undefinedに遭遇するかもしれません:

let person = {
name: "Bob",
age: 30
};

console.log(person.name); // 出力: Bob
console.log(person.job); // 出力: undefined

この場合、person.jobundefinedです。なぜなら、personオブジェクトにjobプロパティを定義していないからです。

NullとUndefined:主要な違い

nullundefinedをそれぞれ探求したので、それらを並べて違いをより理解しやすくしましょう。

要素 null undefined
意味 任意のオブジェクト値の不在 変数が宣言されたが値が割り当てられていない
タイプ オブジェクト 未定義
JSONにおける有効性 有効 無効
デフォルトの関数パラメータ 使用されない オプションのパラメータのデフォルトとして使用される
等価性 null == undefined (true), null === undefined (false) undefined == null (true), undefined === null (false)

以下のコード例でこれらの違いを示します:

// タイプチェック
console.log(typeof null);       // 出力: "object"
console.log(typeof undefined);  // 出力: "undefined"

// JSONシリアライズ
console.log(JSON.stringify({ a: null }));     // 出力: {"a":null}
console.log(JSON.stringify({ a: undefined })); // 出力: {}

// デフォルトの関数パラメータ
function sayHello(name: string = "World") {
console.log(`Hello, ${name}!`);
}

sayHello();        // 出力: Hello, World!
sayHello(undefined); // 出力: Hello, World!
sayHello(null);    // 出力: Hello, null!

// 等価性
console.log(null == undefined);  // 出力: true
console.log(null === undefined); // 出力: false

実際には、nullundefinedの選択は個人やチームの好みによります。しかし、違いを理解することで、より正確でバグのないコードを書くことができます。

最後に、すべてを纏める例を見てみましょう:

function processUser(user: { name: string, age?: number } | null | undefined) {
if (user === null) {
console.log("User explicitly set to null");
} else if (user === undefined) {
console.log("User not provided");
} else {
console.log(`Processing user: ${user.name}, Age: ${user.age ?? "Unknown"}`);
}
}

processUser(null);                    // 出力: User explicitly set to null
processUser(undefined);               // 出力: User not provided
processUser({ name: "Alice" });       // 出力: Processing user: Alice, Age: Unknown
processUser({ name: "Bob", age: 30 }); // 出力: Processing user: Bob, Age: 30

この関数は、nullundefined、および有効なユーザーオブジェクトを異なる方法で処理する実際のシナリオを示しています。

それでは、TypeScriptにおけるnullundefinedのすべてを学びました!実践で完璧にするためには、これらの概念を自分のコードで試してみてください。ハッピーコーディング、そしてあなたの変数が常に意図的にnullまたはundefinedであることを祈っています!

Credits: Image by storyset