Передача функции JavaScript в качестве параметра
Как передать функцию в качестве параметра, не вызывая ее в "родительской" функции и не используя eval()
? (Поскольку я читал, что это небезопасно.)
У меня есть следующий код:
addContact(entityId, refreshContactList());
Это работает, но проблема в том, что refreshContactList
вызывается сразу при выполнении кода, а не тогда, когда я планирую ее использовать внутри функции.
Я мог бы обойти это, используя eval()
, но это не лучшая практика, как я прочитал. Как мне передать функцию в качестве параметра в JavaScript?
5 ответ(ов)
Вам просто нужно убрать скобки:
addContact(entityId, refreshContactList);
Это передаст функцию refreshContactList
как аргумент, не выполняя её сразу.
Вот пример:
function addContact(id, refreshCallback) {
refreshCallback();
// Вы также можете передать аргументы, если это необходимо
// refreshCallback(id);
}
function refreshContactList() {
alert('Hello World');
}
addContact(1, refreshContactList);
Таким образом, функция refreshContactList
будет вызвана внутри addContact
, когда вам это нужно.
Чтобы передать функцию в качестве параметра, просто уберите скобки!
function ToBeCalled(){
alert("Я был вызван");
}
function iNeedParameter(paramFunc) {
// Хорошо проверить, что параметр не равен null
// и что это действительно функция
if (paramFunc && (typeof paramFunc == "function")) {
paramFunc();
}
}
// Это вызывает iNeedParameter и передает ей другую функцию
iNeedParameter(ToBeCalled);
Идея заключается в том, что функция довольно похожа на переменную. Вместо того, чтобы писать
function ToBeCalled() { /* что-то */ }
вы можете написать
var ToBeCalledVariable = function () { /* что-то */ }
Существуют небольшие различия между двумя подходами, но в любом случае оба являются допустимыми способами определения функции. Теперь, если вы определяете функцию и явно присваиваете её переменной, логично, что вы можете передать её в качестве параметра другой функции, и вам не нужны скобки:
anotherFunction(ToBeCalledVariable);
Фраза, распространенная среди программистов JavaScript: "Eval — это зло", поэтому старайтесь избегать его использования любой ценой!
В дополнение к ответу Стива Фентон, вы также можете передавать функции напрямую.
function addContact(entity, refreshFn) {
refreshFn();
}
function callAddContact() {
addContact("entity", function() { DoThis(); });
}
В этом примере вместо использования eval
мы передаем функцию refreshFn
как аргумент в addContact
. Это позволяет избежать потенциальных проблем с безопасностью и производительностью, связанных с использованием eval
.
Я закончила с тем, что отрезала все волосы из-за этой проблемы. Я не смогла заставить работать примеры выше, поэтому в итоге у меня получилось следующее:
function foo(blabla){
var func = new Function(blabla);
func();
}
// Чтобы вызвать это, я просто передала нужную мне JS-функцию в виде строки в новую...
foo("alert('test')");
И это работает безупречно... по крайней мере, для моих нужд. Надеюсь, это кому-то поможет.
Я предлагаю поместить параметры в массив, а затем разделить их с помощью функции .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
как отдельные аргументы. Это удобно, когда количество параметров может варьироваться, и позволяет избежать необходимости явно перечислять их при вызове функции.
Установка значения по умолчанию для параметра функции в JavaScript
Сравнение: var functionName = function() {} против function functionName() {}
В чем разница между call и apply?
JavaScript: Знак плюс перед функциональным выражением
Определение глобальной переменной в функции JavaScript