69. `_.isEqual()`を実装する
シェアしよう
少し工夫が必要 - accepted / - tried
_.isEqualを使えば、複雑なデータ型を比較することが容易にできる。
isEqual
を実装するのはいかがですか?
lodash の実装ではたくさんのデータ型をサポートしているけど、ここでは以下のデータ型だけサポートすれば良い
- primitives
- plain objects (object literals)
- array
Objectを比較するときに、列挙可能な属性だけ見ると良い、prototypeは考慮不要。
const a = {a: 'bfe'}const b = {a: 'bfe'}isEqual(a, b) // truea === b // falseconst c = [1, a, '4']const d = [1, b, '4']isEqual(c, d) // truec === d // false
Lodashの実装では変な挙動がある (github issue)、例えば以下のコード:
const a = {}a.self = aconst b = {self: a}const c = {}c.self = cconst d = {self: {self: a}}const e = {self: {self: b}}
lodash.isEqual
では以下の結果を返してくる。falseがあったことに留意してください。
// result from lodash implementation_.isEqual(a, b) // true_.isEqual(a, c) // true_.isEqual(a, d) // true_.isEqual(a, e) // true_.isEqual(b, c) // true_.isEqual(b, d) // true_.isEqual(b, e) // false_.isEqual(c, d) // true_.isEqual(c, e) // true_.isEqual(d, e) // true
lodashで考慮されたパフォーマンスの懸念を置いといて、この問題では上記の変な共同を避けるべき、つまり上記の例では全部true を返して、さらにmaximum call stack size exceededエラーはならない。