2014-01-15 74 views
1

我正在寫一個單元測試(在與Chai摩卡),看看有些對象,oinstanceofClassY。單元測試成功了,但是我可以讓它失敗,這取決於我如何創建對象字面值,儘管生成的對象字面值是相同的。對象字面值屬性賦值奇怪:這裏發生了什麼?

我知道這有點含糊。讓我再解釋一下。

ClassY是對象的一部分,我們將其稱爲Parent。這種關係簡單地看起來像這樣:

Parent: { 
    ClassY: function() {} 
} 

我附加ParentBackbone使用下劃線延伸方法:
_.extend(Backbone, Parent)

這導致具有ClassY屬性,其可以通過Backbone.ClassY訪問骨幹。

我的單元測試是:
expect(o).to.be.instanceof(Backbone.ClassY);

,我知道一個事實,即oBackbone.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檢查骨幹揭示了我失敗的情況下,ClassY是一個對象。在成功的情況下,它是構造函數。

我想這是對象文字的一些簡單的屬性,逃避我。你知道這裏發生了什麼嗎?

回答

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可以在那裏捅入並將其自身連接起來。再一次,沒有讀過來源,但那是我最初的反應。