Как я могу условно определить функцию в javascript?

Рассмотрим следующий script:

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

Как вы можете видеть, функция foo определена и работает даже при условии, что условие для if терпит неудачу.

Причина, по которой я хочу сделать это, заключается в том, что я разрабатываю расширение для InDesign, и я создал script, называемый utilities.jsx, который содержит различные функции, которые используются в других скриптах. Во всех скриптах, которые нуждаются в этих функциях, я просто использую:

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

который определяет все функции, которые мне нужны, а затем я могу их использовать. Теперь, поскольку этот script будет вызываться несколько раз различными файлами в непредсказуемом порядке (пользователь решает), я думал, что могу определить функции, если они еще не определены (если utilities.jsx не запущен все же). Вид вроде require_once в php.

Я думал о чем-то вроде следующего, но это не работает, поскольку функции определяются каждый раз при запуске script: `

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

Есть ли другие варианты?

Ответ 1

Чтобы гарантировать, что ваша функция еще не определена, используйте:

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

Ответ 2

Вы можете сделать эти выражения функций вместо деклараций функций:

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

Обратите внимание, что в приведенном выше коде foo все еще доступен, даже если условие оценивается как false. Это связано с тем, что объявления (как функция, так и переменная) поднимаются до вершины области, в которой они объявлены. Тем не менее, назначения происходят в точке кода, где они появляются.

Что делает этот код, так это:

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

Предупреждение. Именованные функциональные выражения по-прежнему поднимаются в Internet Explorer 8 и ниже (это ошибка в IE). Очевидно, что это только потенциальная проблема, если вам нужно поддерживать старые браузеры.

Ответ 3

Вы можете использовать указатели функций для переназначения функции по мере необходимости.

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

Ответ 4

Обычно я создаю полный API на основе функции, возвращающей объект, содержащий методы, которые, наконец, вызывают второстепенные функции JS. Расширения могут взаимодействовать с файлами JS со встроенным классом. Кажется, я дал вам ссылку на кулинарию. Итак, что вы можете сделать, это объявить объект в AS3 и проверить наличие какого-либо свойства, например:

public var jsAPI:Object = {};

код js будет

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

Затем, если вам нужно использовать JS-функцию в AS3, вы можете проверить некоторый флаг как:

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