比较详情
- 除
NaN
外,原始值使用==
运算符进行比较。 如果双方都是NaN
,则视为相同。 - 对象的类型标签应该是一样的。
- 仅考虑自有属性。
Error
名称和消息总是被比较,即使它们不是可枚举的属性。- 对象封装器作为对象和未封装的值进行比较。
Object
属性是无序比较的。Map
键和Set
项是无序比较的。- 当双方不同或双方遇到循环引用时,则递归停止。
- 实现不测试对象的
[[Prototype]]
。 - 不比较
Symbol
属性。 WeakMap
和WeakSet
的比较不依赖于它们的值。
以下示例不会抛出 AssertionError
,因为使用 ==
运算符比较原始值。
import assert from 'node:assert';
// 注意:这不会抛出 AssertionError!
assert.deepEqual('+00000000', false);
const assert = require('node:assert');
// 注意:这不会抛出 AssertionError!
assert.deepEqual('+00000000', false);
“深度”相等意味着子对象的可枚举"自有"属性也被评估:
import assert from 'node:assert';
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK
// b 的值不同:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
assert.deepEqual(obj1, obj3);
// OK
// 原型被忽略:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
const assert = require('node:assert');
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK
// b 的值不同:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
assert.deepEqual(obj1, obj3);
// OK
// 原型被忽略:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
如果值不相等,则抛出 AssertionError
,其 message
属性设置为等于 message
参数的值。
如果未定义 message
参数,则分配默认错误消息。
如果 message
参数是 Error
的实例,则将抛出错误而不是 AssertionError
。
- Primitive values are compared with the
==
operator, with the exception ofNaN
. It is treated as being identical in case both sides areNaN
. - Type tags of objects should be the same.
- Only enumerable "own" properties are considered.
Error
names and messages are always compared, even if these are not enumerable properties.- Object wrappers are compared both as objects and unwrapped values.
Object
properties are compared unordered.Map
keys andSet
items are compared unordered.- Recursion stops when both sides differ or both sides encounter a circular reference.
- Implementation does not test the
[[Prototype]]
of objects. Symbol
properties are not compared.WeakMap
andWeakSet
comparison does not rely on their values.
The following example does not throw an AssertionError
because the
primitives are compared using the ==
operator.
import assert from 'node:assert';
// WARNING: This does not throw an AssertionError!
assert.deepEqual('+00000000', false);
const assert = require('node:assert');
// WARNING: This does not throw an AssertionError!
assert.deepEqual('+00000000', false);
"Deep" equality means that the enumerable "own" properties of child objects are evaluated also:
import assert from 'node:assert';
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK
// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
assert.deepEqual(obj1, obj3);
// OK
// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
const assert = require('node:assert');
const obj1 = {
a: {
b: 1
}
};
const obj2 = {
a: {
b: 2
}
};
const obj3 = {
a: {
b: 1
}
};
const obj4 = Object.create(obj1);
assert.deepEqual(obj1, obj1);
// OK
// Values of b are different:
assert.deepEqual(obj1, obj2);
// AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } }
assert.deepEqual(obj1, obj3);
// OK
// Prototypes are ignored:
assert.deepEqual(obj1, obj4);
// AssertionError: { a: { b: 1 } } deepEqual {}
If the values are not equal, an AssertionError
is thrown with a message
property set equal to the value of the message
parameter. If the message
parameter is undefined, a default error message is assigned. If the message
parameter is an instance of an Error
then it will be thrown instead of the
AssertionError
.