[[JavaScript]]では2つの等価演算子が登場し、その意味合いは若干異なります。他の言語を習得済であればあるほど誤解しやすい部分なので、[演算子 · JavaScript Primer \#jsprimer](https://jsprimer.net/basic/operator/)を読んでしっかり理解しましょう。
## Reference
- [演算子 · JavaScript Primer \#jsprimer](https://jsprimer.net/basic/operator/)
## Lesson
[[JavaScript]]には[[等価演算子 (JavaScript)|等価演算子]]と[[厳密等価演算子 (JavaScript)|厳密等価演算子]]があります。**基本的には[[厳密等価演算子 (JavaScript)|厳密等価演算子]]を使います**が、一部例外もあります。
### 等価演算子
型が異なっても[[暗黙的な型変換 (JavaScript)|暗黙的な型変換]]を行い、値が等しい場合に `true` を返す演算子です。逆は[[不等価演算子 (JavaScript)|不等価演算子]]です。
### 厳密等価演算子
型と値の両方が等しい場合にのみ `true` を返す演算子です。逆は[[厳密不等価演算子 (JavaScript)|厳密不等価演算子]]です。
## Mission 1
#🙂NORMAL
次の中で正しい説明を1つ選んでください。
(a) string型のデータ同士を[[厳密等価演算子 (JavaScript)|厳密等価演算子]]で比較してはいけない
(b) 値が無効値([[null (JavaScript)|null]] or [[undefined (JavaScript)|undefined]])かどうかを判定したい場合は、[[等価演算子 (JavaScript)|等価演算子]]を使うメリットがある
(c) [[Object (JavaScript)|Object]]同士の比較は[[厳密等価演算子 (JavaScript)|厳密等価演算子]]ではなく[[等価演算子 (JavaScript)|等価演算子]]を使ったほうがよい
(d) 空の[[オブジェクトリテラル (JavaScript)|オブジェクトリテラル]]同士は[[等価演算子 (JavaScript)|等価演算子]]を使った場合のみ `true` を返す
%%
解答例
正解は(b)。各選択肢の誤りは以下。
(a) [[厳密等価演算子 (JavaScript)|厳密等価演算子]]による比較が普通 ([[Java]]のように `equals` を使う必要はない)
(c) [[厳密等価演算子 (JavaScript)|厳密等価演算子]]より[[等価演算子 (JavaScript)|等価演算子]]を使った方がよいケースは(b)の場合以外はない. また、[[Object (JavaScript)|Object]]の参照が等しいかの確認はどちらでやっても同じ結果になる
(d) 空の[[オブジェクトリテラル (JavaScript)|オブジェクトリテラル]]は毎回新たな参照を生成するため、どちらの演算子を使っても必ず `false` になる
%%
## Mission 2
#😵HARD
以下の関数が期待通り動くように実装を変更してください。
```js
/**
* 2つのオブジェクト objA と objB のプロパティが再帰的に等しいか確認する
* ```js
* expect(isDeepEquals({}, {})).toBe(true);
* expect(isDeepEquals({id: 1, name: "a"}, {id: 1, name: "a"})).toBe(true);
* expect(isDeepEquals({id: 1, name: "a"}, {name: "a", id: 1})).toBe(true);
* expect(isDeepEquals({id: 1, name: "a"}, {id: 2, name: "a"})).toBe(false);
* ```
*/
function isDeepEquals(objA, objB) {
return objA == objB;
}
```
%%
解答例
```js
function isDeepEquals(objA, objB) {
return JSON.stringify(objA, Object.keys(objA).sort()) ==
JSON.stringify(objB, Object.keys(objB).sort());
}
```
%%
> [!hint]- Hint 1
> [[JSON.stringify (JavaScript)|JSON.stringify]]を使います。
### 動作確認をしたい場合
ファイル名を `main.test.js` に変更し、以下のコードを先頭に追加して `deno test` コマンドを実行します。
```js
import { assertEquals } from "jsr:@std/assert";
export function parameterizedTest(name, cases, testFn, toTitle) {
for (const testCase of cases) {
Deno.test(
toTitle?.(name, testCase) ?? `${name} -> ${JSON.stringify(testCase)}`,
() => {
testFn(testCase);
},
);
}
}
parameterizedTest(
"",
[
[{}, {}, true],
[{ id: 1, name: "a" }, { id: 1, name: "a" }, true],
[{ id: 1, name: "a" }, { name: "a", id: 1 }, true],
[{ id: 1, name: "a" }, { id: 2, name: "a" }, false],
],
([args1, args2, expected]) => {
assertEquals(isDeepEquals(args1, args2), expected);
},
);
```
---
*NEXT* >> [[📗TDQ-006 分割代入]]