_x000D_
function isDeepEqual(obj1, obj2, testPrototypes = false) {_x000D_
if (obj1 === obj2) {_x000D_
return true_x000D_
}_x000D_
_x000D_
if (typeof obj1 === "function" && typeof obj2 === "function") {_x000D_
return obj1.toString() === obj2.toString()_x000D_
}_x000D_
_x000D_
if (obj1 instanceof Date && obj2 instanceof Date) {_x000D_
return obj1.getTime() === obj2.getTime()_x000D_
}_x000D_
_x000D_
if (_x000D_
Object.prototype.toString.call(obj1) !==_x000D_
Object.prototype.toString.call(obj2) ||_x000D_
typeof obj1 !== "object"_x000D_
) {_x000D_
return false_x000D_
}_x000D_
_x000D_
const prototypesAreEqual = testPrototypes_x000D_
? isDeepEqual(_x000D_
Object.getPrototypeOf(obj1),_x000D_
Object.getPrototypeOf(obj2),_x000D_
true_x000D_
)_x000D_
: true_x000D_
_x000D_
const obj1Props = Object.getOwnPropertyNames(obj1)_x000D_
const obj2Props = Object.getOwnPropertyNames(obj2)_x000D_
_x000D_
return (_x000D_
obj1Props.length === obj2Props.length &&_x000D_
prototypesAreEqual &&_x000D_
obj1Props.every(prop => isDeepEqual(obj1[prop], obj2[prop]))_x000D_
)_x000D_
}_x000D_
_x000D_
console.log(isDeepEqual({key: 'one'}, {key: 'first'}))_x000D_
console.log(isDeepEqual({key: 'one'}, {key: 'one'}))
_x000D_