2013-05-31 347 views
4

我繼承了一個代碼庫,我需要爲我的工作進行更新。我正在慢慢地學習他們正在試圖用閉包實現的目標,但是當嘗試更新使用此功能的網站的一部分時,我陷入了困境。我將給出代碼試圖完成的基本概述,看看是否有人可以提供幫助。Javascript關閉返回undefined

var TheObject = (function(){ 
    var veryLargeDependantData = { 
     var1: {}, 
     var2: {}, 
     var3: [], 
     //Set these variables via functions 
     function1: function f1(data){...}, 
     function2: function f2(data){...}, 
     initialize: function initialize() { //set values for var1... var3} 
    }; 

    return {initialize: veryLargeDependentData.initialize}; 
})().initialize(); 

因爲我顯然不能在網站上顯示生產代碼,這將不得不做。但基本上非常大型的依賴數據變量是函數的入口。當頁面加載時調用初始化函數,一切都很開心。但是現在我需要將它添加到舊頁面的onclick事件中,並且螢火蟲控制檯表示該變量未定義。在其他頁面中,我可以毫無問題地使用它。

我的問題是什麼魔術正在導致閉包不成爲這樣的可調用名稱空間的一部分。我有點像JavaScript,所以我很抱歉如果這個問題聽起來有誤。

onclick='TheObject.initialize();' 
+0

你能告訴我們'onclick'事件的代碼嗎? – crush

+0

'verylargeDependentData()'不存在於全局範圍內,因此您不能以這種方式調用它。目前只能通過'TheObject.initialize()'調用。 (由於錯別字難以辨認) – crush

+1

'verylargeDependentData'不是一個函數(除了超出範圍之外),你究竟在做什麼?當按下按鈕而不是頁面加載時初始化它? – jerry

回答

5

我假設你的意思是,你要運行在一個click事件處理的initialize功能,而你當前正在嘗試這樣做是這樣的:

TheObject.initialize(); 

如果是這樣的情況下, ,問題在於TheObject實際上是指返回值initialize,因爲您在立即調用的函數表達式的返回值上調用了initialize。有可能initialize返回undefined(很可能,它沒有明確的return聲明)。

爲了解決這個問題,您可能需要刪除立即致電initalize的電話,該電話將允許您在頁面加載和其他任何地方使用上面顯示的行。

+1

我不認爲他想調用Object初始化,他想初始化他的對象並在關閉中保存它的數據。但是他將他的迴歸聲明放在他的變量聲明中,+有錯別字。 –

+1

我想我明白你的意思了,但問題有點混亂,所以我們不能真正知道OP的目標是什麼,除非他們更新它。我認爲拼寫錯誤只是將代碼大幅縮減以便在此處發佈的結果。 –

+0

@JamesAllardice所以你所說的是,如果我將初始化函數的調用刪除到腳本下,我應該可以隨時調用對象。 –

2

在此代碼中,TheObject的值將是veryLargeDependentData.initialize()方法返回的值。如果initialize方法什麼都不返回,TheObject將是未定義的。

簡化示例:

var TheObject = (function() { 
    return { 
    initialize: function() { 
     // stuff happens here, but importantly, there's nothing returned 
    } 
    } 
})().initialize(); 

可以打破這種分解成執行的順序如下:

// the value of step_one is a function that will return an object when it is run 
var step_one = (function() { 
    return { 
    initialize: function() { 
     // ... 
    } 
    } 
}); 

// after running the function step_one, step_two will be an object 
// containing one key - initialize - which is a function 
var step_two = step_one(); 

// since initialize doesn't return anything, TheObject is set to undefined. 
var TheObject = step_two.initialize(); 

可以解決這個問題通過設置TheObject是含有初始化方法的對象然後在需要時再次運行該方法。

var TheObject = (function() { 
    return { 
    initialize: function() { 
    } 
    } 
})(); 

// initialize 
TheObject.initialize(); 

// and again 
TheObject.initialize(); 

請注意!

原作者可能已經打算使初始化方法只運行一次。多次運行它可能會在您的系統中引入錯誤!

+0

不錯的解釋方式。 – crush

1

似乎不必要的複雜,我不確定在這種情況下通過使用匿名函數和閉包獲得了什麼。你有什麼理由不能簡單地做到以下幾點?

var TheObject = { 
    var1: {}, 
    var2: {}, 
    var3: [], 
    //Set these variables via functions 
    function1: function(data){...}, 
    function2: function(data){...}, 
    initialize: function(){alert("initialize");} 
}; 

var initButton = document.getElementById("initButtonName"); 
initButton.addEventListener("click", TheObject.initialize); 

請注意,您要刪除內聯事件。

+0

因爲我是全新的javascript事物,所以我只寫了代碼,並試圖修改其功能。但是你是對的,未來有一天它應該遵循這種模式。 –