比较详情
- 除
NaN
外,原始值使用==
运算符进行比较。 如果双方都是NaN
,则视为相同。 - 对象的类型标签应该是一样的。
- 仅考虑自有属性。
Error
名称和消息总是被比较,即使它们不是可枚举的属性。- 对象封装器作为对象和未封装的值进行比较。
Object
属性是无序比较的。Map
键和Set
项是无序比较的。- 当双方不同或双方遇到循环引用时,则递归停止。
- 实现不测试对象的
[[Prototype]]
。 - 不比较
Symbol
属性。 WeakMap
和WeakSet
的比较不依赖于它们的值。RegExp
的 lastIndex、flags 和 source 总是被比较,即使它们不是可枚举的属性。
以下示例不会抛出 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.RegExp
lastIndex, flags, and source are always compared, even if these are not enumerable properties.
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
.