8

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

1

Как передать функцию в качестве параметра, не вызывая ее в "родительской" функции и не используя eval()? (Поскольку я читал, что это небезопасно.)

У меня есть следующий код:

addContact(entityId, refreshContactList());

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

Я мог бы обойти это, используя eval(), но это не лучшая практика, как я прочитал. Как мне передать функцию в качестве параметра в JavaScript?

5 ответ(ов)

11

Вам просто нужно убрать скобки:

addContact(entityId, refreshContactList);

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

Вот пример:

function addContact(id, refreshCallback) {
    refreshCallback();
    // Вы также можете передать аргументы, если это необходимо
    // refreshCallback(id);
}

function refreshContactList() {
    alert('Hello World');
}

addContact(1, refreshContactList);

Таким образом, функция refreshContactList будет вызвана внутри addContact, когда вам это нужно.

0

Чтобы передать функцию в качестве параметра, просто уберите скобки!

function ToBeCalled(){
  alert("Я был вызван");
}

function iNeedParameter(paramFunc) {
   // Хорошо проверить, что параметр не равен null
   // и что это действительно функция
   if (paramFunc && (typeof paramFunc == "function")) {
      paramFunc();   
   }
}

// Это вызывает iNeedParameter и передает ей другую функцию
iNeedParameter(ToBeCalled); 

Идея заключается в том, что функция довольно похожа на переменную. Вместо того, чтобы писать

function ToBeCalled() { /* что-то */ }

вы можете написать

var ToBeCalledVariable = function () { /* что-то */ }

Существуют небольшие различия между двумя подходами, но в любом случае оба являются допустимыми способами определения функции. Теперь, если вы определяете функцию и явно присваиваете её переменной, логично, что вы можете передать её в качестве параметра другой функции, и вам не нужны скобки:

anotherFunction(ToBeCalledVariable);
0

Фраза, распространенная среди программистов JavaScript: "Eval — это зло", поэтому старайтесь избегать его использования любой ценой!

В дополнение к ответу Стива Фентон, вы также можете передавать функции напрямую.

function addContact(entity, refreshFn) {
    refreshFn();
}

function callAddContact() {
    addContact("entity", function() { DoThis(); });
}

В этом примере вместо использования eval мы передаем функцию refreshFn как аргумент в addContact. Это позволяет избежать потенциальных проблем с безопасностью и производительностью, связанных с использованием eval.

0

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

function foo(blabla){
    var func = new Function(blabla);
    func();
}
// Чтобы вызвать это, я просто передала нужную мне JS-функцию в виде строки в новую...
foo("alert('test')");

И это работает безупречно... по крайней мере, для моих нужд. Надеюсь, это кому-то поможет.

0

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

function addContact(parameters, refreshCallback) {
    refreshCallback.apply(this, parameters);
}

function refreshContactList(int1, int2, str) {
    alert(int1 + int2);
    console.log(str);
}

addContact([1, 2, "str"], refreshContactList); // параметры должны быть помещены в массив

В этом примере функция addContact принимает массив parameters и функцию refreshCallback. При помощи метода .apply() мы можем передать элементы массива в refreshCallback как отдельные аргументы. Это удобно, когда количество параметров может варьироваться, и позволяет избежать необходимости явно перечислять их при вызове функции.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь