Быстрый ответ, который, вероятно, будет уже дан ответ и принят ко времени публикации
Этот ответ заключается в том, что ваша вторая версия вызывает populate_form
, а затем передает результат
функцию , чтобы щелкнуть. Что, в данном случае, не то, что вы хотите. Что .click()
действительно ожидает
ссылка на функцию для выполнения, когда что-то вызывает это событие.
Это быстрый ответ; что может иметь или не иметь смысла сразу. Итак, давайте посмотрим
надумал простой пример. Рассмотрим следующий код:
var Foo = function() {
var noop = function() { };
this.callback = noop;
}
Foo.prototype.setCallback = function(callback) {
this.callback = callback;
}
Foo.prototype.go = function() {
this.callback.apply(this);
}
Это грубое чрезмерное упрощение того, что делает jQuery, но оно все понимает.
У нас есть маленький класс, и у него есть два метода: setCallback
и go
. Теперь идея
что когда мы вызываем go()
, мы хотим выполнить любую функцию, которую мы предоставили. Также обратите внимание, что
по умолчанию callback
устанавливается на пустую функцию (или noop
).
Итак, если мы сделаем это:
var bar = new Foo();
bar.go()
Тогда ничего не произойдет, но мы не получим никаких ошибок. Это потому, что вызывается пустая функция noop
.
Теперь поговорим о двух способах определения функции в JavaScript: Выражение функции и объявление функции.
Объявление функции выглядит так:
function sayHelloDeclaration() {
alert("Hello from a declaration!");
}
И если бы мы хотели вызвать эту функцию, мы бы написали:
sayHelloDeclaration();
И мы бы увидели предупреждение. Однако, если бы мы просто хотели сослаться на саму функцию (не вызывая ее), мы бы просто использовали ее имя:
sayHelloDeclaration;
Обратите внимание на отсутствие скобок; это делает это просто ссылкой на функцию. Никогда не велели выполнять свою работу, поэтому предупреждение никогда не появляется. Теперь давайте вернемся к нашему классу Foo
, а конкретнее к функции setCallback
:
Foo.prototype.setCallback = function(callback) {
this.callback = callback;
}
Обратите внимание, что этот метод принимает один аргумент и присваивает его свойству this
. По сути, мы хотим сохранить ссылку на функцию
для последующего использования. И давайте посмотрим на метод go
:
Foo.prototype.go = function() {
this.callback.apply(this);
}
Это берет все, что хранится в this.callback
и пытается вызвать его, используя, .apply()
, мы могли бы также использовать .call()
(тонкая разница между этими двумя). Или просто сказал бы this.callback()
.
Итак, давайте посмотрим, как это будет использоваться. Если бы я написал ...
function sayHelloDeclaration() {
alert("Hello from a declaration!");
}
var bar = new Foo();
bar.setCallback(sayHelloDeclaration);
... вы бы не увидели всплывающее окно. Однако добавление последней строки ...
function sayHelloDeclaration() {
alert("Hello from a declaration!");
}
var bar = new Foo();
bar.setCallback(sayHelloDeclaration);
bar.go();
... вы увидите всплывающее окно. Это потому, что go()
вызвал ссылку на sayHello
, которую он отслеживал. Тем не менее, ваш второй пример делает что-то вроде этого:
function sayHello() {
alert("Hello from a declaration!");
}
var bar = new Foo();
bar.setCallback(sayHelloDeclaration());
Обратите внимание, что вы получаете всплывающее окно, однако мы никогда не звонили bar.go()
. Это потому, что sayHello()
вызывает метод.
Возвращаемое значение из этой функции передается в setCallback
. Если бы мы попытались позвонить bar.go()
, мы бы получили
ошибка типа, потому что мы попытались установить callback
на что-то, что не было функцией, а затем попытались вызвать ее. Это
"плохая вещь".
А как насчет выражений функций? Выражение функции - это другой способ определения функции. В некотором роде вы можете определить строку или число в JavaScript. Имеет похожую, но немного иную форму:
var sayHelloExpression = function() { alert("Hello from expression"); };
По сути, это создает новую анонимную функцию и присваивает ее переменной sayHelloExpression
. Таким образом, мы можем использовать его так же, как в предыдущем примере:
var bar = new Foo();
bar.setCallback(sayHelloExpression);
bar.go();
Или мы могли бы пропустить присвоение этой переменной все вместе и просто сказать:
var bar = new Foo();
bar.setCallback(function() { alert("Hello from expression"); });
bar.go();
Теперь есть некоторые тонкие (но важные) различия между объявлениями функций и выражениями функций, о которых другие люди узнали более подробно, но здесь необходимо понять, что вы можете говорить о функции, не вызывая ее. Вы также можете отслеживать ссылку на функцию, а затем вызывать ее позже.
В первом случае вы создаете выражение функции, которое вызывает другую функцию с некоторыми аргументами.Так же, как наш alert
в нашем выражении функции, за исключением того, что это определенная пользователем функция.Но то, что вы даете setCallback
, все еще является ссылкой на функцию , которая не будет вызываться до позже .
Наконец, давайте посмотрим наразумное использование для вызова функции, используемой при работе с обратным вызовом, подобным этому.Примером может служить ситуация, когда у вас есть функция, которая возвращает другую функцию.Рассмотрим эту функцию:
function createGreeter(name) {
return function() {
alert("Hello there " + name + "!!")
}
}
Эта функция принимает один аргумент, а затем создает и возвращает другую функцию.
var sayHiBob = createGreeter("Bob");
sayHiBob(); // alerts "Hello there Bob!!"
Эта функция похожа на небольшую фабрику длянам создавать другие функции с.В этом случае имеет смысл использовать эту функцию при ее использовании с нашим методом setCallback
, потому что мы хотим установить обратный вызов для результата функции, котораямы призываем.Примерно так.
var bar = new Foo();
bar.setCallback(createGreeter("Joe"));
bar.go(); // alerts "Hello there Joe!!"
Есть еще много всего, чему можно научиться, но это мой длинный ответ на этот вопрос.