0

assert我在node.js的模块中遇到了一些奇怪的行为。我不确定这是错误还是预期行为。

当我创建一个数组,然后在第三个元素上初始化一个值时,前两个元素是未定义的。测试前两个元素是否未定义返回 true,但是将数组作为一个整体与undefined前两个元素进行比较失败。

var assert = require('assert');

var a = [];
a[2] = 2;
console.log(a);    // [ , , 2 ]

assert.equal(a[0], undefined);                  // ok
assert.equal(a[1], undefined);                  // ok
assert.equal(a[2], 2);                          // ok
assert.deepEqual(a, [, , 2]);                   // ok
assert.deepEqual(a, [undefined, undefined, 2]); // error ???

我可以理解 undefined 元素和具有 value 的元素之间存在差异undefined,因为ArrayextendsObject和数组元素只是对象上的属性。

但是为什么最后一个断言失败了?

4

4 回答 4

4

很可能是因为[,,2]并且[undefined,undefined,2]没有相同数量的键:

> Object.keys([,,2]).length
1
> Object.keys([undefined,undefined,2]).length
3

这是检查此代码的相关部分。assert

于 2013-11-07T19:46:55.587 回答
2

我要在这里踏出一条腿...

最有可能的是,deepEqual使用hasOwnPropertyobject 的方法来确保它不会捕获任何继承的属性。

如果是这种情况,以下控制台日志可能会对您有所帮助:

var test1 = [];
undefined

test1[2] = "xyzzy";
"xyzzy"

test1.hasOwnProperty(0)
false

test1.hasOwnProperty(1)
false

test1.hasOwnProperty(2)
true

var test2 = [undefined, undefined, "plugh"];
undefined

test2.hasOwnProperty(0)
true

test2.hasOwnProperty(1)
true

test2.hasOwnProperty(2)
true
于 2013-11-07T19:40:55.907 回答
0

我冒险猜测一下。似乎不包含任何内容(即未初始化)和 are 的数组位置undefined与实际将实际值粘贴undefined到数组中的特定位置之间存在区别。

您实际上可以在控制台日志中的 Chrome 中看到这一点:

> a = [undefined, undefined, 2];
  [undefined, undefined, 2]

> b = [,,2]
  [undefined × 2, 2]

> c = [];
> c[2] = 2;
> c
  [undefined × 2, 2]

这是一个非常微妙的区别;在第一种情况 ([,,2]) 中,您创建了一个没有任何位置的数组,0并且1; 它是一个备用数组,其中只有位置3包含一个值。在第二种情况下,您创建了一个不是备用阵列的阵列。undefined相反,您专门在位置1和处插入了值2。看来这两种情况的处理方式不同,这可能就是它们不相等的原因。

我认为将第一个数组可视化为[,,2] = [uninitialized, uninitialized, 2]. 因此,区别在于未初始化的值与已插入数组中的具体未定义(这意味着该位置未初始化)。

更新

我看了看里面的代码assert.js具体来说,请注意第 221 和 222 行:

 if (ka.length != kb.length)
    return false;

kakb在第 213-215 行中设置:

 var ka = Object.keys(a),
        kb = Object.keys(b),
        key, i;

Object.keys(a).lengthfor的值为,而for的[,,2]值为。这就是他们不平等的原因。1Object.keys(b).length[undefined, undefined, 2]3

于 2013-11-07T19:44:44.027 回答
0

不是错误。这些数组有不同的行为。考虑以下用例:

function log(item, idx) {
    console.log(item, " - ", idx);
}

a.map(log); // 2 - 2

[undefined, undefined, 2].map(log); //undefined - 0 undefined - 0 2 - 2
于 2013-11-07T19:44:56.963 回答