ps0*_*604 5 javascript jasmine jasmine2.0
在这个 Jasmine 测试中,我比较了两个几乎相同的对象,唯一的区别是第二个对象有一个额外的未定义成员。
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);
});
Run Code Online (Sandbox Code Playgroud)
测试失败,但是打印两个对象会JSON.stringify产生两个相同的输出。
{"a":1,"b":2}
{"a":1,"b":2}
Run Code Online (Sandbox Code Playgroud)
浏览物体可以发现差异,但在复杂的物体中这并不容易。关于如何解决这个问题有什么建议吗?
你的问题基于两个误解:
obj2 c是一个值为 的已定义属性undefined。stringify()不undefined根据规范进行序列化 - 您的测试不安全两个对象是不平等的。
toEqual()toEqual使用内部函数util.equals(),它将逐个比较对象中a和b中定义的所有可枚举键。
经过一些类型检查后,它开始比较对象的键
查看 ECMAscript 规范。Put创建对象文字时会调用此内部方法:
[...]
生成式 PropertyNameAndValueList : PropertyAssignment 的计算如下:
- 令 obj 为通过表达式 new Object() 创建新对象的结果,其中 Object 是具有该名称的标准内置构造函数。
- 令 propId 为计算 PropertyAssignment 的结果。
- 使用参数 propId.name、propId.descriptor 和false调用 obj 的 [[DefineOwnProperty]] 内部方法。
- 返回对象。
[...]
产生式 PropertyAssignment : PropertyName :AssignmentExpression 的计算如下:
- 令 propName 为计算 PropertyName 的结果。
- 令exprValue 为AssignmentExpression 的计算结果。
- 令 propValue 为 GetValue(exprValue)。
- 令 desc 为属性描述符{[[Value]]: propValue, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}
类似地通过成员表达式定义属性:
8.12.5 [[Put]] ( P, V, Throw ) 当使用属性 P、值 V 和布尔标志 Throw 调用 O 的 [[Put]] 内部方法时,将执行以下步骤:
[...]
否则,在对象 O 上创建一个名为 P 的命名数据属性,如下所示
A。令 newDesc 为属性描述符 {[[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}。
b. 调用 O 的 [[DefineOwnProperty]] 内部方法,传递 P、newDesc 和 Throw 作为参数。
的实现在8.12.9 [[DefineOwnProperty]] (P, Desc, Throw)DefineOwnProperty中描述,不再重复。MDN还表示,即使默认值也是.undefined
查看:
> var obj2 = {a: 1, b: 2, c: undefined };
> obj2.hasOwnProperty("c");
< true
Run Code Online (Sandbox Code Playgroud)
stringify()查看JSON 规范上的ECMAscript 规范stringify():
(来源:json.org)
这是 ECMAscript 规范的一部分:
- 否则 A. 令 K 为内部字符串列表,由 [[Enumerable]] 属性为 true 的 value 的所有自身属性的名称组成。字符串的顺序应与 Object.keys 标准内置函数使用的顺序相同。
他们说,该对象的枚举属性应该符合 的顺序(和结果)Object.keys()。让我们测试一下...
> var obj2 = {a: 1, b: 2, c: undefined };
> Object.keys(obj2);
< ["a", "b", "c"]
Run Code Online (Sandbox Code Playgroud)
呃,他们是对的!
然后有一个Str()函数定义处理值的行为undefined。有几个If Type() ...步骤不适用于未定义的值,以
- 返回未定义。
当被对象序列化器调用时:
对于 K 的每个元素 P。
A。令 strP 为使用参数 P 和 value 调用抽象操作 Str 的结果。
b. 如果 strP 不是未定义的
[...]
| 归档时间: |
|
| 查看次数: |
3484 次 |
| 最近记录: |