2012-06-14 19 views
11

請看下面的代碼:如何在JavaScript中有條件地定義函數?

if (false)​ { 
    function foo() { 
     alert("FOO"); 
    } 
} 
foo(); // alerts "FOO" 

正如你所看到的,功能foo定義並且即使在if條件失敗的作品。

我想這樣做的原因是我正在開發InDesign的擴展,並且我製作了一個名爲utilities.jsx的腳本,其中包含在其他腳本中使用的各種功能。在需要這些功能的所有腳本,我簡單地使用:

app.doScript(File(scriptsFile.parent.fsName + "/t_utilities.jsx"), ScriptLanguage.JAVASCRIPT); 

定義我需要的所有功能,然後我就可以使用它們。現在,由於這個腳本將被不同的文件以不可預知的順序多次調用(用戶決定),我想我可能只定義這些函數,如果它們之前沒有定義過(如果utilities.jsx還沒有運行) 。有點像在PHP中的require_once

我想的是類似於以下,但隨着功能的每次腳本運行時定義的不工作:`

var utilitiesHasRun; 
if (utilitiesHasRun !== true) { 
    // define all the functions 
    // ... 
    utilitiesHasRun = true; 
} 

是否還有其他選擇嗎?

+2

您的第一個代碼片段在技術上並不有效,因爲函數聲明不允許在塊內使用。它只能起作用,因爲所有主流瀏覽器都實現了ECMAScript規範的擴展來處理這種情況。 –

+0

爲了繼續@ TimDown的評論,如果它是嚴格模式代碼的一部分,你的第一個片段實際上會拋出一個SyntaxError。 –

回答

6

爲了保證您的功能尚未定義,使用:

if (typeof yourFunctionName == 'undefined') { 
    yourFunctionName = function(params) { 
    // your code here 
    }; 
} 
+0

如果'yourFunctionName'最初沒有定義,這會引發錯誤。 'typeof yourFunctionName =='undefined''雖然可以工作。 –

+0

@JuanMendes點採取和糾正。 – Sirko

15

你可以讓他們發揮作用表達而不是函數聲明

if (false)​ { 
    var foo = function() { 
     alert("FOO"); 
    }; 
} 
foo(); //TypeError: undefined is not a function 

注意,在上面的代碼中,foo是即使條件評估爲假仍可訪問。這是因爲聲明(包括函數和變量)被提升到聲明範圍的頂部。但是,作業發生在它們出現的代碼中。

什麼上面的代碼切實做好這就是:

var foo; //No assignment, foo is undefined 
if (false)​ { 
    foo = function() { 
     alert("FOO"); 
    }; 
} 
foo(); //TypeError: undefined is not a function 

警告 - 命名的函數表達式在Internet Explorer 8和下方(這是在IE中的錯誤)仍然懸掛。顯然這只是一個潛在的問題,如果你需要支持舊的瀏覽器。

+1

+1:非常簡潔。我沒有意識到函數聲明仍然存在,認爲它只是函數表達式,但現在我看到了細微的差別! –

+0

+1啊,提升。感謝您解釋這一點。我選擇了Sirko的答案,因爲它不會產生錯誤,但是如果你只是在try塊中調用foo('foo()'),你的解決方案也可以工作,防止錯誤破壞腳本。 – Shawn

+0

另外一個Firefox中的bug顯然是 –

3

您可以根據需要使用函數指針重新分配函數。

var myFunctionPointer = function { alert("Default"); }; 
if (condition) { 
    myFunctionPointer = function { alert("true"); }; 
} 
else { 
    myFunctionPointer = function { alert("false"); }; 
} 
myFunctionPointer(); 
0

通常我創建一個返回含有終於方法的對象基於一個功能完整的API調用未成年JS功能。擴展可以與嵌入類的JS文件進行交互。我想我給你了食譜的鏈接。所以,你可以做的是在AS3中聲明的對象和檢查像一些屬性:

public var jsAPI:Object = {}; 

JS代碼將

var jsAPI = function() { 
    return { 
     hasBeenLoaded:false, 
     myMethod1:function(){}, 
    } 
} 

然後,如果你需要在AS3使用JS功能,您可以檢查一些標誌,如:

if (jsAPI.hasBeenLoaded){ … } 
else { //loads the API via new API() }