Передача функции с параметрами в качестве параметра?


151

Можно ли передать функцию javascript с параметрами в качестве параметра?

Пример:

$(edit_link).click( changeViewMode( myvar ) );

5
Похоже, JQuery, и, скорее всего, так, но это не имеет значения. Использование или параметры и функции одинаковы независимо от того, какие библиотеки Javascript вы используете.
Гуффа

@Guffa - мне было интересно, стоит ли отмечать его jQuery
Russ Cam

1
@Lucia Пожалуйста, подумайте об изменении принятого ответа на это .
Михал Перлаковский

Если вы работаете с React, подумайте над stackoverflow.com/questions/41369497/…
Майкл Фрейдгейм

Ответы:


244

Используйте «закрытие»:

$(edit_link).click(function(){ return changeViewMode(myvar); });

Это создает анонимную временную оболочку функции, которая знает о параметре и передает его фактической реализации обратного вызова.


3
Если вы хотите вызвать функцию объекта, вам нужно вызвать bind (). myObj.click (function () {this.doSomething ();} .bind (myObj)); Это сделает «это» myObj.
Эли

1
Разве это не проблема с производительностью при работе со многими из них? Например, вы рендеринг onPress в ряд, и у вас есть 10000 строк. Это создает новую временную оболочку анонимной функции для каждой строки. Есть ли другой способ сделать это?
Джошуа Пинтер

@JoshuaPinter Сама техника не проблема. Если вам требуется один и тот же вызов функции 10000 раз, вы можете просто сохранить оболочку в переменной, чтобы создать ее только один раз. Если вам нужно пройти 10 000 различных контекстов, вы мало что можете сделать. Остерегайтесь преждевременной оптимизации: как всегда, с производительностью, вы должны измерить, чтобы увидеть, есть ли проблема или нет. Современные механизмы JavaScript очень мощные и могут оптимизировать код неожиданными способами.
Фердинанд Бейер

@FerdinandBeyer Отлично, спасибо за совет. Друг сказал мне, что это плохая практика, и что вы должны вместо этого использовать this.myFunction = this.myFunction.bind(this)в своем constructorметоде. Но, как вы сказали, когда вам нужно передать разные контексты для каждого из них, например, для всех разных строк, по которым вы щелкаете, чтобы открыть страницу с подробностями этой строки, это невозможно избежать.
Джошуа Пинтер

@FerdinandBeyer, допустим, что myvar является строкой, и она изменяется между двумя последовательными вызовами передачи changeViewMode как замыкания, но changeViewMode всегда получает первое значение myvar, я хочу вызвать функцию замыкания с другим значением аргумента, назначенным для той же переменной myvar,
nmxprime

42

Использование Function.prototype.bind(). Цитируя MDN:

bind()Метод создает новую функцию , которая при вызове, имеет свой thisнабор ключевых предоставленному значения с заданной последовательности аргументов , предшествующих любой при условии , когда новая функция вызывается.

Он поддерживается всеми основными браузерами, включая IE9 +.

Ваш код должен выглядеть так:

$(edit_link).click(changeViewMode.bind(null, myvar));

Примечание: я предполагаю, что вы находитесь в глобальном контексте, т.е. thisпеременная есть window; в противном случае используйте thisвместо null.


Спасибо, это помогло мне. Использовал это так:$.ajax(url).done(handler.bind(this, var1, var2));
Томас

2
Какой вариант лучше? Использование замыкания или использование функции связывания? Пожалуйста, дайте мне знать, если это повлияет на производительность
Varun


15

Нет, но вы можете передать один без параметров, и сделать это:

$(edit_link).click(
  function() { changeViewMode(myvar); }
);

Таким образом, вы передаете анонимную функцию без параметров, которая затем вызывает вашу параметризованную функцию с переменной в закрытии



7

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

$(edit_link).click(() => changeViewMode(myvar));

2

Ты можешь сделать это

var message  = 'Hello World';

var callback = function(){
alert(this)
}.bind(message);

а потом

function activate(callback){
  callback && callback();
}

activate(callback);

Или, если ваш обратный вызов содержит более гибкую логику, вы можете передать объект.

демонстрация


2

Вот пример, следующий за подходом Фердинанда Бейера:

function function1()
{
    function2(function () { function3("parameter value"); });
}
function function2(functionToBindOnClick)
{
    $(".myButton").click(functionToBindOnClick);
}
function function3(message) { alert(message); }

В этом примере «значение параметра» передается от function1 к function3 через function2 с помощью переноса функции.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.