考虑以下脚本:
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;
}
还有其他选择吗?
答案 0 :(得分:15)
您可以将它们设为表达式而不是函数声明:
if (false) {
var foo = function () {
alert("FOO");
};
}
foo(); //TypeError: undefined is not a function
请注意,在上面的代码中,即使条件评估为false,仍然可以访问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 :(得分:8)
为确保您之前未定义过您的功能,请使用:
if ( typeof yourFunctionName == 'undefined' ) {
yourFunctionName = function( params ) {
// your code here
};
}
答案 2 :(得分:3)
您可以根据需要使用函数指针重新分配函数。
var myFunctionPointer = function { alert("Default"); };
if (condition) {
myFunctionPointer = function { alert("true"); };
}
else {
myFunctionPointer = function { alert("false"); };
}
myFunctionPointer();
答案 3 :(得分: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() }