Node.js 两个空数组似乎不相等

Node.js 两个空数组似乎不相等,node.js,coffeescript,underscore.js,Node.js,Coffeescript,Underscore.js,我正在进行一些测试,并试图断言在对象初始化时设置了属性: var Varity = exports.Varity = function Varity () { this.options = extend({}, standardOptions, Varity._globalOptions); this.expectations = []; }; 然后在我的测试中: When -> @varity = new @subject.Varity() Then -> expect(

我正在进行一些测试,并试图断言在对象初始化时设置了属性:

var Varity = exports.Varity = function Varity () {
  this.options = extend({}, standardOptions, Varity._globalOptions);
  this.expectations = [];
};
然后在我的测试中:

When -> @varity = new @subject.Varity()
Then -> expect(@varity.expectations).to.deep.equal([])
FWIW,我正在使用摩卡咖啡,并提供了摩卡咖啡和(希望很明显)咖啡脚本。断言库实际上是
实际上是
(这是我写的东西)。我相当肯定,
确实
正在发挥作用1)以下是正确的:

expect([]).to.deep.equal([])
和2),在构造函数末尾和测试中记录@varity.expections,表明它是一个空数组

我还将日志放在了
的实现中,以确保它到达了正确的代码路径,并且我已经记录了那里的实际情况和期望情况。它们都以
[]
的身份登录。实际上,在
内部,我正在使用.isEqual进行深入的对象比较。记录以下内容将返回false:

_(actual).isEqual(expectation); // where actual is "@varity.expectations" and expectation is "[]"
因此,我将代码跟踪到
\
的实现中,并开始记录。并发现挂起在这里(在
eq
方法中-我刚刚搜索了isEqual,如果有人想查看代码本身,这是第一次命中):

将aCtor和bCtor记录为:

[Function: Array]
所以它们看起来是相等的,但是我放在
if
中的日志运行,所以
aCtor!==bCtor
的计算结果为真

为了彻底起见,以下内容也同样适用:

expect(@varity.expectations.join('').split('')).to.deep.equal([])
expect(@varity.expectations.toString()).to.deep.equal([].toString())
expect(JSON.stringify(@varity.expectations)).to.deep.equal(JSON.stringify([]))
expect([].slice.call(@varity.expectations)).to.deep.equal([])
但这是错误的:

expect(@varity.expectations.constructor).to.deep.equal([].constructor)
这是真的:

expect(@varity.expectations.constructor.toString()).to.deep.equal([].constructor.toString())
这是一个隐藏(不可枚举)属性抛出比较的情况吗?我没有在
上设置任何其他内容。expections
(实际上,这里打印的代码-变量构造函数-是整个构造函数)

编辑: 我猜这个问题与咖啡脚本有关。两个相同的函数不是
==

function () {} === function () {} // false

只有当它们实际上是相同的函数时,它们才相等。理论上,两个数组构造函数应该是相同的函数。事实上他们不是,这让我怀疑问题在于咖啡脚本。其中一个数组来自coffeescript,另一个来自javascript。我无法想象coffeescript没有使用默认的数组构造函数,但可能在编译时发生了某种神奇的事情?作为参考,我使用的是coffeescript版本1.6.1(并且仅用于测试)。

首先,我认为我的
库确实没有问题,这是正确的。我最近在
should.js
中观察到了同样的行为

第二,这是一个咖啡脚本编译的东西。类编译为表达式(而不是声明),这意味着:

class Foo
编译成

var Foo;
Foo = (function() {
  function Foo() {}
  return Foo;
})();
而不是

Foo = function Foo () {}
因此,Foo的构造函数是
[Function:Function]
(闭包),而不是
[Function:Foo]
。数组似乎是这样,导致javascript中生成的空数组(或对象)与coffeescript中生成的空数组(或对象)不同

第三,我已经为此编写了一个下划线修复程序,用于测试:

_.mixin({
    fix: function(thing) {
        return JSON.parse(JSON.stringify(thing));
    }
});
可以这样称呼:

Then -> expect(_.fix(@varity.expectations)).to.deep.equal([])

我去掉了摩卡标签,因为这绝对不是摩卡的问题。也许是咖啡脚本(我想还是不太可能),但不是摩卡咖啡。
Then -> expect(_.fix(@varity.expectations)).to.deep.equal([])