すべての根底となる[[Truthy (JavaScript)|Truthy]]、[[Falsy (Elixir)|Falsy]]、[[Nullish (JavaScript)|Nullish]]について理解したうえで、いくつかの演算子を学びましょう。 ## Reference - [演算子 · JavaScript Primer \#jsprimer](https://jsprimer.net/basic/operator/) ## Lesson ### Truthy/Falsy/Nullish [[Truthy (JavaScript)|Truthy]]と[[Falsy]]、[[Nullish (JavaScript)|Nullish]]は似て非なるものです。しっかり違いを把握しておきましょう。これを理解しなければ、このあとの話は理解できません。 | 値 | Truthy | Falsy | Nullish | | ------------------------------------- | ------ | ----- | ------- | | [[undefined (JavaScript)\|undefined]] | No | Yes | Yes | | [[null (JavaScript)\|null]] | No | Yes | Yes | | 0 or 0n | No | Yes | **No** | | "" | No | Yes | **No** | | [[NaN (JavaScript)\|NaN]] | No | Yes | **No** | ### 論理積演算子 [[論理積演算子 (JavaScript)|論理積演算子]]は、`a && b` としたとき `a` が [[Truthy (JavaScript)|Truthy]] であれば `b` を返し、そうでなければ `a` を返却する演算子です。 ```js "a" && "b" // "b" "a" && "b" && "c" // "c" "" && "b" // "" ``` ### 論理和演算子 [[論理和演算子 (JavaScript)|論理和演算子]]は、`a || b` としたとき `a` が [[Truthy (JavaScript)|Truthy]] であれば `a` を返し、そうでなければ `b` を返却する演算子です。 ```js "a" || "b" // "a" "a" || "b" || "c" // "a" "" || "b" // "b" ``` ### Null合体演算子 [[Null合体演算子 (JavaScript)|Null合体演算子]]は、`a ?? b` としたとき `a` が [[Nullish (JavaScript)|Nullish]] であれば `b` を返し、そうでなければ `a` を返却する演算子です。 ```js console.log("a" ?? "b"); // "a" console.log("a" ?? "b" ?? "c"); // "a" console.log("" ?? "b"); // "" console.log(null ?? "b"); // "b" console.log(undefined ?? "b"); // "b" ``` ### 論理否定演算子 [[論理否定演算子 (JavaScript)|論理否定演算子]]は、`!a` としたとき `a` が [[Truthy (JavaScript)|Truthy]] であれば `false` を返し、そうでなければ `true` を返す演算子です。 ```js console.log(!true); // false console.log(!false); // true console.log(!"hoge"); // false console.log(!""); // true console.log(!undefined); // true ``` ## Mission 1 #🙂NORMAL 以下のコードは関数の実装が間違っています。コードを修正してください。 ```js /** * 引数がすべて空文字ではないことを確認します * @param {string} str1 * @param {string} str2 * @param {string} str3 * @returns {boolean} 結果 */ function notIncludesEmpty(str1, str2, str3) { return str1 && str2 && str3; } ``` %% 解答例 ```js /** * 引数がすべて空文字ではないことを確認します * @param {string} str1 * @param {string} str2 * @param {string} str3 * @returns {boolean} 結果 */ function notIncludesEmpty(str1, str2, str3) { return Boolean(str1 && str2 && str3); } ``` %% > [!hint]- Hint 1 > [[#論理積演算子]]の仕様を確認し、どのようなルールで何の[[データ型 (JavaScript)|データ型]]を返却するのか確認してみましょう。 ## Mission 2 #🙂NORMAL 以下のコードは関数の実装が間違っており、`c` に空文字を指定した場合も `@` が結合されてしまいます。**コードの総文字数が変わらない**ように修正してください。 ```js /** * 3つの文字列を結合します。 * cは省略可能であり、その場合は"@"として結合します。 * * @param {string} a * @param {string} b * @param {string} [c="@"] * @returns {string} 結合された文字列 */ function join(a, b, c) { return a + b + (c || "@"); } ``` %% 解答例 ```js /** * 3つの文字列を結合します。 * cは省略可能であり、その場合は"@"として結合します。 * * @param {string} a * @param {string} b * @param {string} [c="@"] * @returns {string} 結合された文字列 */ function join(a, b, c) { return a + b + (c ?? "@"); } ``` %% > [!hint]- Hint 1 > [[#論理和演算子]]の仕様を確認し、どのようなルールで何の[[データ型 (JavaScript)|データ型]]を返却するのか確認してみましょう。 ## Mission 3 #😵HARD 以下のコードは関数の実装が間違っています。問題が発生する『不具合の概要』『期待値』『原因』『解決方法(コード)』を説明してください。 ```js /** * moneyを渡すとおつりを返却します。 * * - moneyが未指定(またはundefined or null)の場合はundefinedを返却します * - moneyには数値型以外の値が入らないという前提があります * - moneyが50未満の場合におつりがマイナスになることは許容します * * @param {number} money * @returns {number|undefined} おつり */ function pay(money) { if (!money) { return undefined; } return money - 50; } ``` %% 解答例 【不具合の概要】 `pay(0)` を指定すると `undefined` が返却されてしまう。 【期待値】 `-50` が返却されること。 【原因】 `!money` で [[論理否定演算子 (JavaScript)|論理否定演算子]]に `0` が指定されるが、`0` は [[Truthy (JavaScript)|Truthy]]ではない ([[Falsy (JavaScript)|Falsy]]である) ため、結果が `true` となり、if文の中で `undefined` が返却されるから。 【解決方法】 [[不等価演算子 (JavaScript)|不等価演算子]]を使って `undefined` or `null` を判定する。 ```js /** * moneyを渡すとおつりを返却します。 * * - moneyが未指定(またはundefined or null)の場合はundefinedを返却します * - moneyには数値型以外の値が入らないという前提があります * * @param {number} money * @returns {number|undefined} おつり */ function pay(money) { if (money == null) { return undefined; } return money - 50; } ``` %% > [!hint]- Hint 1 > [[#論理否定演算子]]が[[Falsy (JavaScript)|Falsy]]な値に対してどう振る舞うかを見直してみましょう。 > [!hint]- Hint 2 > [[📗TDQ-005 等価演算子と厳密等価演算子]] で学んだ内容を使います。 --- *NEXT* >> [[📗TDQ-008 関数]]