2016-06-08 132 views
2

我已經定義了一個輔助類來創建一些對象。 由於對象A包含Bs,我試圖從createA調用createB,但是我得到一個「未捕獲的引用錯誤:createB未定義爲」。 JS是不是我的主要語言,所以請原諒我,如果這件事情明顯;)Javascript - 從另一個靜態方法訪問靜態方法拋出ReferenceError

這裏是我的代碼:

define([ 
    "model/A", 
    "model/B", 
    "model/C" 
], function (A, B, C) { 
    return { 
    addTo: function (params, key, target, source) { 
     if (params[key] !== undefined && params[key] !== null) { 
     target.set(key, params[key], source); 
     } 
    }, 
    createA: function (params, source) { 
     var result = new A(); 

     ... 
     bDefs.forEach(function(bDef) { 
     result.get("bs").push(this.createB(params,source)); 
     }); 
     return result; 
    }, 
    createB: function (params, source) { 

     var result = new B(); 
     ... 

     result.get("cs").push(createC(params,source)); 
     return result; 
    }, 
    createMediaType: function (params, source) { 

     var result = new C(); 
     ... 

     return result; 
    } 
    }; 
}); 

編輯:復讀的問題,我注意到我省略了一些重要的東西,可能是問題的原因:我從forEach中調用createB()。我猜想匿名函數沒有其他類的可見性。如何將這個的引用傳遞給forEach?

+0

這是不行的SO編輯這樣的問題該編輯將使現有問題的答案無效,因此我已從您用編輯添加的createB調用中刪除了'this.'。作爲[algiogia說](http://stackoverflow.com/questions/37696799/javascript-accessing-static-method-from-another-static-method-throws-reference/376​​96945?noredirect=1#comment62869281_37696945),解決方案我的回答也涉及到「forEach」問題。我還更新了答案,向您展示如何使用'this'來實現'forEach'的工作。 –

+0

@ T.J.Crowder我編輯了這個問題,因爲它是錯誤的。在SO中複製代碼我省略了相關部分。在我剛纔提到的初始版本中,我已經嘗試過使用「this.createB()」。你的回答仍然有效。 – algiogia

+0

即使您錯誤地發佈了代碼,它也不適合修復它*一旦收到答案,它就會失效*。但是,正如你注意到的那樣,你最初的問題* *在最後關於'this.createB'(我錯過了!)有那麼一點,所以它不適用於這種情況。順便說一句,在我上面的評論中,我的意思是「正如jamiec所說的」不是「,因爲algiogia說」 - 哈哈! –

回答

1

此行

result.get("bs").push(createB(params,source)); 

預計將有稱爲createB一個在範圍內的標識符。代碼中沒有一個。對象初始值設定項中的屬性鍵不會成爲獨立標識符(幸好)。

假設createA將與this一起被稱爲您使用初始化程序創建的對象,您可以使用this.createB代替。但它需要假設約this,這將需要執行代碼使用您的對象。我在下面給你一個替代方案。

I'm calling createB() from within a forEach . I suppose that anonymous function does not have visibility of the rest of the class.

是的,它的確如此。 (這不是一個類。)

How can I pass a reference to this to the forEach ?

的第二個參數forEach是價值回調期間this使用,所以:

bDefs.forEach(function(bDef) { 
    result.get("bs").push(this.createB(params,source)); 
}, this); 
// ^^^^ 

或交替您可以使用Function#bind,但我不會'那裏。

如果您正在使用ES2015(又名「ES6」),可以產生它們在那裏使用箭頭功能,因爲箭頭功能關閉了上下文的this值:

// Requires ES2015 ("ES6") 
bDefs.forEach(bDef => { 
    result.get("bs").push(this.createB(params,source)); 
}); 

您有第二個選項不依賴調用代碼來調用正確的this值,並且不要求您在forEach內保留該值:您可以在私有範圍內將這些函數獨立標識符生成並返回他們作爲對象的屬性:

define([ 
    "model/A", 
    "model/B", 
    "model/C" 
], function (A, B, C) { 
    // Note how each of these is a function declaration; that defines 
    // their names as in-scope identifiers within this anonymous function 
    // and the functions created within it (which close over the context of 
    // the call to this anonymous function where these are created). 
    function addTo(params, key, target, source) { 
    if (params[key] !== undefined && params[key] !== null) { 
     target.set(key, params[key], source); 
    } 
    } 

    function createA(params, source) { 
    var result = new A(); 

    ... 
    result.get("bs").push(createB(params,source)); 

    return result; 
    } 

    function createB(params, source) { 

    var result = new B(); 
    ... 

    result.get("cs").push(createC(params,source)); 
    return result; 
    } 

    function createMediaType(params, source) { 

    var result = new C(); 
    ... 

    return result; 
    } 

    // Now we return the object 
    return { 
     addTo: addTo, 
     createA: createA, 
     createB: createB, 
     createMediaType: createMediaType 
    }; 
}); 

邊注:在ES2015(又名「ES6」)結尾的那段對象初始化可以多一點簡潔:

// Requires ES2015 (aka "ES6") 
return { 
    addTo, 
    createA, 
    createB, 
    createMediaType 
}; 
+0

謝謝。我發現問題是forEach(請參閱更新的問題)。 – algiogia

+1

@algiogia如果按照此答案中顯示的方式進行操作,它也可以解決您的forEach問題。 – Jamiec

+0

@algiogia:有什麼需要澄清的東西嗎? –