В чем разница между возвратом функции и использованием function.innerFunction? - PullRequest
4 голосов
/ 26 мая 2011

Это общий вопрос о чем-то, с чем я часто сталкиваюсь: Когда я должен использовать

function Bla(){return function(){alert("bla");}}

и вызов основной функции Bla, и когда я должен использовать

function Bla(){function innerBla(){alert("bla");}}

и звоните Bla.innerBla?

В чем разница между ними?

1 Ответ

8 голосов
/ 26 мая 2011

Это два разных способа ведения дел, и они действуют по-разному.

Первая - это функция, которая возвращает другую функцию. Таким образом, чтобы вызвать внутреннюю функцию, вам нужно сначала вызвать внешнюю Bla (которая возвращает внутреннюю), а затем вызвать возвращенное значение (внутренняя функция):

function Bla(){
    return function(){
      alert("bla");
    }
}

Bla()(); // will alert "bla"

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

function Bla(){
    function innerBla () {
      alert("bla");
    }
}

Bla(); // will do 'nothing'

Bla.innerBla равно undefined, поскольку объект (функции - это объекты в JavaScript) Bla не имеет члена с именем innerBla, прикрепленного к нему.


Если вы хотите вызвать его как bla.innerBla, вы должны сделать что-то вроде этого:

function bla () { /* */ }

bla.innerBla = function () {
    alert("bla");
};

bla.innerBla(); 
// will alert "bla" because the `bla` object now has a member called `innerBla`.

Или у вас может быть что-то вроде этого (шаблон, который я часто использую):

function bla () {
    return {
        innerBla: function () {
            alert("bla");
        }
    };
}

bla().innerBla(); // will also alert "bla"

Если вы хотите использовать шаблон конструктора (new), вам нужно сделать что-то вроде этого:

var bla = function () {
  this.innerBla = function () {
    alert("bla");
  };
};

var b = new bla();
b.innerBla();

Это эквивалентно общедоступному свойству экземпляра объекта на языке OO.


И, наконец, если вы хотите выставлять innerBla каждым «экземпляром» (достигается с помощью конструктора, то есть, вызывая bla с использованием ключевого слова new) из bla, вы должны добавить функцию к bar.prototype.innerBla :

var bla = function () { /* */ };
bla.prototype.innerBla = function () {
  alert("bla");
};

var b1 = new bla(), 
    b2 = new bla();

b1.innerBla(); // will alert "bla"
b2.innerBla(); // will also alert "bla"

Это похоже на статический метод.


В дополнение к этому, избегайте именования функций с начальной заглавной буквой (pascal-case), потому что по соглашению обычно мы используем только заглавные буквы функций, которые необходимо вызывать с помощью ключевого слова new (конструкторы). 1049 *

...