Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80529 views
1
var pSlice = Array.prototype.slice;
2
var objectKeys = require('./lib/keys.js');
3
var isArguments = require('./lib/is_arguments.js');
4
5
var deepEqual = module.exports = function (actual, expected, opts) {
6
if (!opts) opts = {};
7
// 7.1. All identical values are equivalent, as determined by ===.
8
if (actual === expected) {
9
return true;
10
11
} else if (actual instanceof Date && expected instanceof Date) {
12
return actual.getTime() === expected.getTime();
13
14
// 7.3. Other pairs that do not both pass typeof value == 'object',
15
// equivalence is determined by ==.
16
} else if (typeof actual != 'object' && typeof expected != 'object') {
17
return opts.strict ? actual === expected : actual == expected;
18
19
// 7.4. For all other Object pairs, including Array objects, equivalence is
20
// determined by having the same number of owned properties (as verified
21
// with Object.prototype.hasOwnProperty.call), the same set of keys
22
// (although not necessarily the same order), equivalent values for every
23
// corresponding key, and an identical 'prototype' property. Note: this
24
// accounts for both named and indexed properties on Arrays.
25
} else {
26
return objEquiv(actual, expected, opts);
27
}
28
}
29
30
function isUndefinedOrNull(value) {
31
return value === null || value === undefined;
32
}
33
34
function isBuffer (x) {
35
if (!x || typeof x !== 'object' || typeof x.length !== 'number') return false;
36
if (typeof x.copy !== 'function' || typeof x.slice !== 'function') {
37
return false;
38
}
39
if (x.length > 0 && typeof x[0] !== 'number') return false;
40
return true;
41
}
42
43
function objEquiv(a, b, opts) {
44
var i, key;
45
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
46
return false;
47
// an identical 'prototype' property.
48
if (a.prototype !== b.prototype) return false;
49
//~~~I've managed to break Object.keys through screwy arguments passing.
50
// Converting to array solves the problem.
51
if (isArguments(a)) {
52
if (!isArguments(b)) {
53
return false;
54
}
55
a = pSlice.call(a);
56
b = pSlice.call(b);
57
return deepEqual(a, b, opts);
58
}
59
if (isBuffer(a)) {
60
if (!isBuffer(b)) {
61
return false;
62
}
63
if (a.length !== b.length) return false;
64
for (i = 0; i < a.length; i++) {
65
if (a[i] !== b[i]) return false;
66
}
67
return true;
68
}
69
try {
70
var ka = objectKeys(a),
71
kb = objectKeys(b);
72
} catch (e) {//happens when one is a string literal and the other isn't
73
return false;
74
}
75
// having the same number of owned properties (keys incorporates
76
// hasOwnProperty)
77
if (ka.length != kb.length)
78
return false;
79
//the same set of keys (although not necessarily the same order),
80
ka.sort();
81
kb.sort();
82
//~~~cheap key test
83
for (i = ka.length - 1; i >= 0; i--) {
84
if (ka[i] != kb[i])
85
return false;
86
}
87
//equivalent values for every corresponding key, and
88
//~~~possibly expensive deep test
89
for (i = ka.length - 1; i >= 0; i--) {
90
key = ka[i];
91
if (!deepEqual(a[key], b[key], opts)) return false;
92
}
93
return typeof a === typeof b;
94
}
95
96