2011-09-30 87 views
4

我試圖定義一個類,在它的構造函數,實例化其他對象,並將它們傳遞對自身的引用:參考當前對象的構造

var Child = function(m) { 
    var mother = m; 

    return { 
    mother: mother 
    } 
} 

var Mother = function() { 
    var children = makeChildren(); 

    return { 
    children: children 
    } 

    function makeChildren() { 
    var children = []; 
    for (var i = 0; i < 10; i++) { 
     var c = new Child(this);  // <--- 'this' is an empty object here 
     children.push(c) 
    } 
    return children; 
    } 
} 

這不起作用,和兒童實例最終會在其mother屬性中有一個空對象。什麼是正確的方法來做到這一點?

回答

3

Javascript的this不是詞彙。這意味着makeChildren得到它的自己this而不是得到Motherthis你想要的。

爲此設置一個普通變量並代之以使用它。

var that = this; 
function makeChildren(){ 
    blabla = that; 
} 

我不認爲這樣做是剛夠雖然。通過從構造函數中返回一個對象,您將忽略this。設置的東西:

this.children = children; 

而不是返回一個新的對象。

+0

設置'this.children = makeChildren()'工作。這通常被認爲是比從構造函數返回對象更好的模式嗎? – Andre

+0

它只是當做一個使用'new'語法的構造函數時,你得到一個'this'來處理(並且這個繼承自原型等)。如果你打算有一個函數返回它自己的東西,不需要訪問這個繼承或訪問原型方法,你可能會使它成爲一個普通的非構造函數。 (並且將名稱改爲非大寫字母,Convention認爲對於需要'new'操作符的東西) – hugomg

1

你可以嘗試傳遞一個參考媽媽的對象,當你從母親對象中調用makeChildren(),像這樣也許:

var Mother = function() { 
    var children = makeChildren(this); 
} 

的makeChildren()函數就可以接受作爲參數參考,你可以使用:

function makeChildren(ref) 
var c = new Child(ref); 

不知道這是否會工作,但它可能是值得一試。

+1

用魔法'這個'變量玩遊戲通常會讓一個人失蹤。我喜歡這個解決方案,因爲它很簡單,直接,而且'makeChildren'不必以特殊的方式被調用以使其正常工作。 –

1

嵌套函數不繼承其父this,所以內makeChildren()this是不一樣的母親構造內的this除非你明確地把它叫makeChildren()時:

var children = makeChildren.call(this); 

這應該工作而不需要對代碼進行任何更改。查看more detail about .call()的MDN。

另外,您可以參考保存到this並傳遞到函數:

var Mother = function() { 
    var self = this; // <-- new variable 

    var children = makeChildren(); 

    return { 
    children: children 
    } 

    function makeChildren() { 
    var children = []; 
    for (var i = 0; i < 10; i++) { 
     var c = new Child(self);  // <--- change 'this' to 'self' 
     children.push(c) 
    } 
    return children; 
    } 
} 

一個函數中的局部變量是嵌套函數訪問。

+0

自變量只能從Mother函數內訪問嗎?除非你明確地通過參考? –

+0

@jayp:內部函數可以使用其範圍內的所有變量,這包括來自外部函數的變量。 – hugomg

+0

出於某種原因,我認爲makeChildren不是一個內在的功能,但分開 - 顯然我沒有正確閱讀。謝謝。 –

0
var Child = function(m) { 
    var mother = m; 

    return { 
     mother: mother 
    } 
}; 

var Mother = function() { 
    if (!(this instanceof Mother)) { 
     return new Mother(); 
    } 

    var that = this; 

    var makeChildren = function() { 

     var children = []; 
     for (var i = 0; i < 10; i++) { 
      var c = new Child(that); // <--- 'that' is the reference to Mother 
      children.push(c) 
     } 

     return children; 
    }; 

    var children = makeChildren(); 

    return { 
     children: children 
    } 
}; 

然後執行:

var m = Mother(); 

前三行的Mother對象確保that值是Mother實例,而不是全局對象。沒有它們,你總是必須寫:

var m = new Mother();