14

考虑以下脚本:

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

如您所见,foo即使条件if失败,该函数也已定义并有效。

我想这样做的原因是我正在为 InDesign 开发一个扩展,并且我制作了一个名为 utility.jsx 的脚本,其中包含在其他脚本中使用的各种功能。在所有需要这些功能的脚本中,我简单地使用:

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

它定义了我需要的所有功能,然后我可以使用它们。现在,由于这个脚本将被各种文件以不可预知的顺序(用户决定)多次调用,我想我可能只定义以前没有定义过的函数(如果实用程序.jsx 还没有运行) . 有点像require_once在php中。

我正在考虑类似以下的内容,但这不起作用,因为每次运行脚本时都会定义函数:`

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

还有其他选择吗?

4

4 回答 4

20

您可以使它们成为函数表达式而不是函数声明

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

请注意,在上面的代码中,foo即使条件评估为 false,仍然可以访问。这是因为函数范围的声明(函数和var)被提升到声明它们的范围的顶部。但是,分配发生在代码中它们出现的位置。

上面的代码实际上在做的是:

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

警告- 命名函数表达式在 Internet Explorer 8 及更低版本中仍然被提升(这是 IE 中的一个错误)。显然,如果您需要支持旧浏览器,这只是一个潜在的问题。

于 2012-06-14T14:17:14.767 回答
8

为确保您的函数之前未定义,请使用:

if ( typeof yourFunctionName == 'undefined' ) {
  yourFunctionName = function( params ) {
    // your code here
  };
}
于 2012-06-14T14:18:38.513 回答
3

您可以根据需要使用函数指针重新分配函数。

var myFunctionPointer = function { alert("Default"); };
if (condition) {
    myFunctionPointer = function { alert("true"); };
}
else {
    myFunctionPointer = function { alert("false"); };
}
myFunctionPointer();
于 2012-06-14T14:17:45.453 回答
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() }
于 2012-06-14T22:16:00.373 回答