How to make a class with private properties so lodash isEqual
returns false when comparing any 2 instances with different items in the private properties?
For example, in the following code isEqual
comparison of the 2 instances of the Bobcat class with different items results in true
. I want to have false
. Is there any Map method missing or anything?
const _ = require('lodash')
class Bobcat {
#items;
constructor() {
this.#items = new Map()
}
set(key, value) {
return this.#items.set(key, value)
}
get(key) {
return this.#items.get(key)
}
has(key) {
return this.#items.has(key)
}
delete(key) {
return this.#items.delete(key)
}
clear() {
this.#items.clear()
}
keys() {
return this.#items.keys()
}
values() {
return this.#items.values()
}
entries() {
return this.#items.entries()
}
forEach(callbackFn, thisArg) {
return this.#items.forEach(callbackFn, thisArg)
}
[Symbol.iterator]() {
return this.#items[Symbol.iterator]()
}
}
const cat1 = new Bobcat()
cat1.set('a', 1)
const cat2 = new Bobcat()
cat2.set('a', 2)
console.log(_.isEqual(cat1, cat2))
// true
Another requirement is to have the comparison outside of the class. No comparison method should be added to the class itself. For example, I don't want
class Bobcat {
isEqual(otherCat) {
...
}
}
or any specific to lodash functionality like
class Bobcat {
[Symbol.for('lodash.isEqual')](otherCat) {
...
}
}
Customizing toStringTag
to return Map
solves the issue for me without changing the downstream code on the isEqual comparison.
get [Symbol.toStringTag]() {
return 'Map'
}
Entire code
const _ = require('lodash')
class Bobcat {
#items
constructor() {
this.#items = new Map()
}
set(key, value) {
return this.#items.set(key, value)
}
get(key) {
return this.#items.get(key)
}
has(key) {
return this.#items.has(key)
}
delete(key) {
return this.#items.delete(key)
}
clear() {
this.#items.clear()
}
keys() {
return this.#items.keys()
}
values() {
return this.#items.values()
}
entries() {
return this.#items.entries()
}
forEach(callbackFn, thisArg) {
return this.#items.forEach(callbackFn, thisArg)
}
[Symbol.iterator]() {
return this.#items[Symbol.iterator]()
}
get size() {
return this.#items.size
}
get [Symbol.toStringTag]() {
return 'Map'
}
}
const cat1 = new Bobcat()
cat1.set('a', 1)
const cat2 = new Bobcat()
cat2.set('a', 1)
// true
console.log('equal1', _.isEqual(cat1, cat2))
cat2.set('a', 2)
// false
console.log('equal2', _.isEqual(cat1, cat2))