gpt4 book ai didi

javascript - Jasmine toEqual 失败但打印两个对象是相同的

转载 作者:行者123 更新时间:2023-12-04 17:53:38 26 4
gpt4 key购买 nike

In this Jasmine test我比较了两个几乎相同的对象,唯一的区别是第二个对象多了一个未定义的成员。

describe('Testing', function () {

it('should compare two objects', function () {


var obj1 = {a: 1, b: 2 };

var obj2 = {a: 1, b: 2, c: undefined };

console.log(JSON.stringify(obj1));
console.log(JSON.stringify(obj2));

expect(obj1).toEqual(obj2);


});

测试失败,但是使用 JSON.stringify 打印两个对象会导致两个相同的输出。

{"a":1,"b":2}
{"a":1,"b":2}

浏览对象可以发现差异,但在复杂的对象中,这并不容易。关于如何处理这个问题有什么建议吗?

最佳答案

您的问题基于两个误解:

  1. obj2 中,c 是一个已定义的属性,其值为 undefined
  2. stringify() 未根据规范序列化 undefined - 您的测试不安全

两个对象不相等

关于 Jasmine toEqual()

toEqual使用内部 util.equals()对于 ab 中定义的所有 可枚举 键,它将逐键比较对象键。

经过一些类型检查后,它进入了 comparing the keys of the object

关于定义属性

查看 ECMAscript 规范。当您创建对象文字时,将调用此内部 Put 方法:

11.1.5 Object Initialiser

[...]

The production PropertyNameAndValueList : PropertyAssignment is evaluated as follows:

  1. Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
  2. Let propId be the result of evaluating PropertyAssignment.
  3. Call the [[DefineOwnProperty]] internal method of obj with arguments propId.name, propId.descriptor, and false.
  4. Return obj.

[...]

The production PropertyAssignment : PropertyName : AssignmentExpression is evaluated as follows:

  1. Let propName be the result of evaluating PropertyName.
  2. Let exprValue be the result of evaluating AssignmentExpression.
  3. Let propValue be GetValue(exprValue).
  4. Let desc be the Property Descriptor{[[Value]]: propValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}

类似的通过成员表达式定义属性:

8.12.5 [[Put]] ( P, V, Throw ) When the [[Put]] internal method of O is called with property P, value V, and Boolean flag Throw, the following steps are taken:

[...]

  1. Else, create a named data property named P on object O as follows

    a. Let newDesc be the Property Descriptor {[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}.

    b. Call the [[DefineOwnProperty]] internal method of O passing P, newDesc, and Throw as arguments.

DefineOwnProperty 的实现,在 8.12.9 [[DefineOwnProperty]] (P, Desc, Throw) 中有描述,不再赘述。还有 MDN says即使是默认值也是 undefined

检查:

> var obj2 = {a: 1, b: 2, c: undefined };
> obj2.hasOwnProperty("c");
< true

关于stringify()

看看 ECMAscript spec on stringify()或在 JSON spec :

Possible JSON values

(来源:json.org)

这是 ECMAscript 规范的一部分:

  1. Else a. Let K be an internal List of Strings consisting of the names of all the own properties of value whose [[Enumerable]] attribute is true. The ordering of the Strings should be the same as that used by the Object.keys standard built-in function.

他们说,该对象的枚举属性应符合 Object.keys() 的顺序(和结果)。让我们测试一下......

> var obj2 = {a: 1, b: 2, c: undefined };
> Object.keys(obj2);
< ["a", "b", "c"]

嗯,他们是对的!

然后是 Str() 函数,它定义了处理 undefined 值的行为。有几个 If Type() ... 步骤不适用于 undefined 值,以

结尾
  1. Return undefined.

当被对象序列化器调用时:

  1. For each element P of K.

    a. Let strP be the result of calling the abstract operation Str with arguments P and value.

    b. If strP is not undefined

    [...]

关于javascript - Jasmine toEqual 失败但打印两个对象是相同的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42264188/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com