我正在编写一个单元测试(在带有Chai的Mocha中),以查看某个对象o
是否为instanceof
ClassY
。单元测试成功,但我可以使它失败取决于我如何创建一个对象文字,尽管生成的对象文字是相同的。
我知道,这有点模糊。让我解释一下。
ClassY
是对象的一部分,我们将其称为Parent
。这种关系看起来像这样:
Parent: {
ClassY: function() {}
}
我使用Underscore扩展方法将Parent
附加到Backbone
:
_.extend( Backbone, Parent )
这导致Backbone具有ClassY
属性,可以通过Backbone.ClassY
访问。
我的单元测试是:
expect( o ).to.be.instanceof( Backbone.ClassY );
我知道o
是Backbone.ClassY
的实例。
如果我写的话传递:
var Parent = {};
var ClassY = Parent.ClassY = function() {};
以及
var Parent = {};
var ClassY = function() {};
Parent.ClassY = ClassY;
但是当我写下以下内容时,单元测试失败:
var ClassY = function() {};
var Parent = {
ClassY: ClassY
};
失败的原因是:
TypeError: '[object Object]' is not a valid argument for 'instanceof'
(evaluating 'flag(this, 'object') instanceof constructor')
确实,在Chrome DevTools中检查Backbone会在失败的情况下向我显示,ClassY
是一个对象。在成功的情况下,它是构造函数。
我想这是对象文字的一些简单属性,这让我望而却步。你知道这里发生了什么吗?
答案 0 :(得分:1)
我不确定Backbone在这里做了什么(基于对JS中各种“类”/继承实现的了解,我有一些关于为什么会发生这种情况的想法,但我必须看看在图书馆)。
然而,我可以告诉你的是,这是图书馆正在做的事情,而不是对象本身的事情。
以下是您的证明:
var Parent_1 = {
ClassX : function () { this.x = "x"; }
},
ClassY = function () { this.y = "y"; },
Parent_2 = {
ClassY : ClassY
};
var littleX = new Parent_1.ClassX(),
littleY = new Parent_2.ClassY();
littleX instanceof Parent_1.ClassX;
littleY instanceof Parent_2.ClassY;
这两个都应该是真的。
在JS中,当您执行以下操作时:
var x = {}, y = [];
x.y = y;
你给它引用了该对象的完全相同的实例(数字/字符串/布尔值的工作方式不同)。
所以x.y === y
为真,而{} === {}
为假,即使两个对象都具有相同的属性。
在骨干网中,我会想象你正在传递它,Backbone正在寻找一个构造函数并操纵它来附加助手或钩子,或者添加额外的继承或MVC功能/观察等等。
所以来自另一方的东西并不是完全相同的对象,在内存中 - 它可能埋在一个闭包中,然后Backbone可以在某个地方捅,然后将自己连接起来。再说一遍,还没看过来源,但那是我最初的反应。