はじめに
業務でオブジェクトの比較を行うことがあって、等価演算子を使って実装したら思った動きになりませんでした。
下記のイメージになります。
const objectCarA = {
make : "Toyota",
model : "Corolla",
color : "red"
}
const objectCarB = {
make : "Toyota",
model : "Corolla",
color : "red"
}
const isEqualCars = objectCarA === objectCarB
console.log(isEqualCars) // false (あれ、trueにならないの?)
先輩にその理由を教えてもらったので、ここにまとめます。
参照型(オブジェクト型) 基本型(プリミティブ型)
JavaScript のデータ型は、大きく2つに分けて 「基本型(プリミティブ型)」と「参照型(オブジェクト型)」があります。
この違いは変数に値を格納する方法です。
以下に詳細を記載していきます。
参照型(オブジェクト型)とは
参照型のデータで定義された変数は、その変数内に**アドレス(データの住所のようなもの)**を持ちます。
実データは、メモリ上に存在し、変数にはそのメモリのアドレスが格納されるというわけです。
なので、CarAとCarBを統合演算子で比較した際は、アドレスを比較していたのでfalseが返ってきたというわけですね。
具体的には次のようなデータ型があります。
- オブジェクト(object)
- 配列(array)
- 関数(function)
基本型(プリミティブ型)とは
基本型は、値を変数に直接格納します。なので、変数をそのまま統合演算子で比較しても、中身が同じであればtrueが返ります。
const numberA = 10
const numberB = 10
const isEqualNumber = numberA === numberB
console.log(isEqualNumber) // true
どう比較するか
Objectの比較を一からコードで対応しようとすると下記のような関数を作成する必要があります。
function isEqualCars(obj1, obj2) {
if (
obj1.make === obj2.make &&
obj1.model === obj2.model &&
obj1.color === obj2.color
) {
return true
}
return false
}
console.log("ObjectFunction: " + isEqualCars(objectCarA, objectCarB)) // true
ただ、この関数は、他のObjectには使えないですし、比較するたびにつどつど関数を作成するのは手間がかかります。
こういう問題はすでに誰かが解決してくれており、あるメソッドを使うことで一発で解決できます。
lodashのisEqualを使おう
lodashというライブラリがあり、その中のisEqual関数をもちいれば、オブジェクトの比較が一発で行えます。
lodashには配列操作などの便利メソッドがたくさんあるそうなので、色々調べてみたいですね。
const isEqualCars = isEqual(objectCarA, objectCarB)
console.log(isEqualCars) // true
参考記事