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

Мне нравится организовывать свой javascript в стиле пространства имен, как показано ниже. Что я хочу знать: есть ли другой (более короткий?) Способ вызвать myFirstFunction() из mySecondFunction()? Я пробовал this.myFirstFunction(), и он не работает, поэтому, возможно, здесь есть какой-то таинственный трюк, который я не знаю.

var myNameSpace = {
    myFirstFunction: function(){
        alert("Hello World!");
    },
    mySecondFunction: function(){
        myNameSpace.myFirstFunction();
    }
}

Спасибо за вашу помощь, как обычно, люди SO!:)

Ответ 1

Как написано в вашем примере кода, this.myFirstFunction() будет работать. Ваш код, вероятно, упрощен, чтобы проиллюстрировать вашу проблему, поэтому, вероятно, это поможет увидеть фактический код, чтобы узнать, почему он не работает с this.

Одна из возможных причин отказа в том, что код, который вы называете this.myFirstFunction(), находится внутри замыкания. Если это так, this будет ссылкой на функцию закрытия, а не на ваше пространство имен и поэтому будет терпеть неудачу. См. здесь для надуманного примера, основанного на вашем коде, чтобы понять, что я имею в виду. Опять же, просмотр фактического кода, вероятно, будет полезен для диагностики того, что происходит.

Ответ 2

Ваше предложение использовать 'this' должно работать. то есть:.

var myNameSpace = {
    myFirstFunction: function(){
        alert("Hello World!");
    },
    mySecondFunction: function(){
        this.myFirstFunction();
    }
}

Результат:

myNameSpace.mySecondFunction() // "Hello World!".

Ответ 3

Если вы хотите, чтобы он был короче, возможно, вам следует рассмотреть следующий шаблон:

Предложение шаблона дизайна Javascript

в основном для вашего примера:

var myNameSpace = (function()
{
    function _myFirstFunction(){
        alert("Hello World!");
    }

    function _mySecondFunction(){
        _myFirstFunction();
    }

    return {
        MyFirstFunction : _myFirstFunction,    
        MySecondFunction : _mySecondFunction
    };
})();

Я считаю, что это самый чистый шаблон, также предоставляющий "частные/общедоступные" переменные в javascript, что в противном случае практически невозможно.

Ответ 4

В некоторых случаях ключевое слово this должно работать нормально. Если вы явно вызываете myNameSpace.mySecondFunction(), тогда this.myFirstFunction() будет выполняться по назначению.

Если вы используете myNameSpace.mySecondFunction в качестве обработчика событий, скорее всего этого не будет. В случае обработчика событий вам потребуется какой-то способ ссылаться на пространство имен, которое вы хотите использовать. Многие фреймворки JavaScript предоставляют возможность определить, к чему относится ключевое слово this. Например, в MooTools вы можете сделать myNameSpace.mySecondFunction.bind(myNameSpace), что приведет к тому, что this будет ссылаться на myNameSpace внутри mySecondFunction. Если вы не используете фреймворк, вы можете сделать свой обработчик событий анонимной функцией, например:

document.getElementById('myId').addEventListener('click', function(e) {
  myNameSpace.mySecondFunction.call(myNameSpace);
});

Для получения дополнительной информации о методе вызова я хотел бы обратиться к странице MDC для функции вызова или вы могли бы использовать apply, который ведет себя аналогично вызову, но передает массив аргументов для второго параметра, вместо того, чтобы использовать дополнительные параметры, такие как varargs.

Все эти предложения основаны на определении вашего пространства имен @Harnish:

var myNameSpace = {
  myFirstFunction: function(){
    alert("Hello World!");
  },
  mySecondFunction: function(){
    this.myFirstFunction();
  }
}

Для получения дополнительной информации о привязке функций JavaScript я настоятельно рекомендую прочитать статью Justin о области функций и привязке в JavaScript

Ответ 5

Если вы прикрепляетесь к событию:

Возможная проблема может возникнуть, если вы добавляете функцию Namespace к событию, например:

$(el).on("click", nameSpace.myFunc);

....

nameSpace = {

    myFunc: function(){
       this.anotherFunc();
    }

}

что приведет к ошибке.

Решение 1

Вы можете изменить this.anotherFunc() на nameSpace.anotherFunc()

Решение 2

Вы можете изменить

$(el).on("click", nameSpace.myFunc);
// to ----->
$(el).on("click", function(){ nameSpace.myFunc(); }  );