Передача функції з параметрами як параметр?


151

Чи можна передавати функцію javascript з параметрами як параметр?

Приклад:

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

5
Це схоже на JQuery, і, швидше за все, так, але це не має значення. Використання або параметри та функції однакові незалежно від того, які бібліотеки Javascript ви використовуєте.
Гуффа

@Guffa - Мені було цікаво, чи слід позначати його jQuery
Russ Cam

1
@Lucia Будь ласка, подумайте про зміну прийнятої відповіді на це .
Michał Perłakowski

Якщо ви працюєте з React, вважають stackoverflow.com/questions/41369497 / ...
Майкл Freidgeim

Відповіді:


244

Використовуйте "закриття":

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

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


3
Якщо ви хочете викликати функцію на об'єкті, вам потрібно зателефонувати bind (). myObj.click (function () {this.doSomething ();} .bind (myObj)); Це зробить "це" myObj.
Елі

1
Хіба це не проблема ефективності, коли ми маємо багато з них? Наприклад, ви показуєте onPress в рядку і у вас є 10 000 рядків. Це створює нову анонімну обгортку тимчасової функції для кожного рядка. Чи є якийсь інший спосіб зробити це?
Джошуа Пінтер

@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));
Thomas

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); }

У цьому прикладі "значення параметра" передається від функції1 до функції3 через функцію2 за допомогою обгортки функції.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.