They must have the exact same prototype chain, the closest we can do is
test the constructor.
Actually, you can test the prototype:
if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) {
return false;
}
It sounds like you want:
- To be objects:
typeof x === "object"
is the best way to check
- Them to have the same prototype chain: see above
- To have exactly the same properties: you can use
for-in
for all enumerable properties, or getOwnPropertyNames
for all string-named properties (including non-enumerable), or getOwnPropertySymbols
for all Symbol-named properties (including non-enumerable), or Reflect.ownKeys
for both string-named and Symbol-named properties
- A shallow comparison
If so, something along these lines should get you started:
function equals(x, y) {
// If both x and y are null or undefined and exactly the same
if (x === y) {
return true;
}
// If they are not strictly equal, they both need to be Objects
if (typeof x !== "object" || typeof y !== "object") {
return false;
}
// Can't compare `null` with non-`null`
if (!x || !y) { // This works because we did the `x === y` check earlier)
return false;
}
// They must have the exact same prototype chain
if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) {
return false;
}
// Compare own properties (including non-enumerable ones)
const xkeys = Reflect.ownKeys(x);
const ykeys = Reflect.ownKeys(y);
if (xkeys.length !== ykeys.length) {
return false;
}
for (const key of xkeys) {
if (!ykeys.includes(key) || x[key] !== y[key]) {
return false;
}
}
return true;
}
Live Example:
function equals(x, y) {
// If both x and y are null or undefined and exactly the same
if (x === y) {
return true;
}
// If they are not strictly equal, they both need to be Objects
if (typeof x !== "object" || typeof y !== "object") {
return false;
}
// Can't compare `null` with non-`null`
if (!x || !y) { // This works because we did the `x === y` check earlier)
return false;
}
// They must have the exact same prototype chain
if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) {
return false;
}
// Compare own properties (including non-enumerable ones)
const xkeys = Reflect.ownKeys(x);
const ykeys = Reflect.ownKeys(y);
if (xkeys.length !== ykeys.length) {
return false;
}
for (const key of xkeys) {
if (!ykeys.includes(key) || x[key] !== y[key]) {
return false;
}
}
return true;
}
const d1 = [{ deviceid: "867874031097770", simno: "232ff33", slot: "1" },{ deviceid: "86787403100", simno: "ss343433", slot: "2" }];
const d2 = { deviceid: "867874031097770", simno: "232ff33", slot: "1" };
for (const [index, entry] of d1.entries()) {
console.log(`${index}: ${equals(entry, d2)}`);
}
It doesn't check inherited properties, though. If you wanted to do that, you'd probably have a helper function like this to get all properties:
function getAllPropertyKeys(obj) {
const result = new Set();
while (obj && obj !== Object.prototype) {
for (const key of Reflect.ownKeys(obj)) {
result.add(key);
}
obj = Object.getPrototypeOf(obj);
}
return [...result];
}
...then use that instead of Reflect.ownKeys
.
Live Example:
function getAllPropertyKeys(obj) {
const result = new Set();
while (obj && obj !== Object.prototype) {
for (const key of Reflect.ownKeys(obj)) {
result.add(key);
}
obj = Object.getPrototypeOf(obj);
}
return [...result];
}
function equals(x, y) {
// If both x and y are null or undefined and exactly the same
if (x === y) {
return true;
}
// If they are not strictly equal, they both need to be Objects
if (typeof x !== "object" || typeof y !== "object") {
return false;
}
// Can't compare `null` with non-`null`
if (!x || !y) { // This works because we did the `x === y` check earlier)
return false;
}
// They must have the exact same prototype chain
if (Object.getPrototypeOf(x) !== Object.getPrototypeOf(y)) {
return false;
}
// Compare own properties (including non-enumerable ones)
const xkeys = getAllPropertyKeys(x);
const ykeys = getAllPropertyKeys(y);
if (xkeys.length !== ykeys.length) {
return false;
}
for (const key of xkeys) {
if (!ykeys.includes(key) || x[key] !== y[key]) {
return false;
}
}
return true;
}
const d1 = [{ deviceid: "867874031097770", simno: "232ff33", slot: "1" },{ deviceid: "86787403100", simno: "ss343433", slot: "2" }];
const d2 = { deviceid: "867874031097770", simno: "232ff33", slot: "1" };
for (const [index, entry] of d1.entries()) {
console.log(`${index}: ${equals(entry, d2)}`);
}