Odpowiedzi:
typeof callback === "function"
Wszystkie obecne odpowiedzi używają dosłownego ciągu, którego wolę nie mieć w kodzie, jeśli to możliwe - to nie (i zapewnia cenne znaczenie semantyczne, aby uruchomić):
function isFunction(possibleFunction) {
return typeof(possibleFunction) === typeof(Function);
}
Osobiście staram się zmniejszyć liczbę ciągów znaków w moim kodzie ...
Ponadto, chociaż zdaję sobie sprawę, że typeof
jest to operator, a nie funkcja, korzystanie ze składni, która sprawia, że wygląda ona na tę drugą, jest niewielkie.
isFunction(not_defined))
gdzie not_defined
jest nazwa funkcji, która nie jest zdefiniowana i FireBug zwrócił, not_defined is not defined
co jest poprawne, ale twoja funkcja powinna zwrócić wartość false i nie generować błędu ...
not_defined
, aby przekazać jego wartość isFunction()
i nie może go rozwiązać. Nic nie można zrobić z definicją isFunction()
rozwiązania tego problemu.
isFunction
i rób tylko (typeof no_function == typeof Function)
.
typeof(Function())
ponieważ Function jest funkcją; ale podobnie jak Array, Object i inne wbudowane prototypy (z braku lepszego terminu). Jeśli sprawdzałeś tablicę, której typeof(array) === typeof(Array)
na przykład nie używałbyś ; użyjesz tego, typeof(array) === typeof(Array())
ponieważ faktycznie musisz ocenić funkcję, jeśli jesteś ostrożny i konsekwentny.
if (callback && typeof(callback) == "function")
Należy zauważyć, że wywołania zwrotnego (przez siebie) ma wartość false
, jeśli jest undefined
, null
, 0
, lub false
. Porównywanie do null
jest zbyt specyficzne.
callback
sama wartość ma wartość „fałsz-y”, to jej typof nigdy nie może być „funkcją”.
Te metody określania, czy funkcja jest zaimplementowana, również zawodzą, jeśli zmienna nie jest zdefiniowana, dlatego używamy czegoś mocniejszego, który obsługuje otrzymywanie łańcucha:
function isFunctionDefined(functionName) {
if(eval("typeof(" + functionName + ") == typeof(Function)")) {
return true;
}
}
if (isFunctionDefined('myFunction')) {
myFunction(foo);
}
typeof window.doesthisexist
zamiast doesthisexist
. Jednak użycie eval (która: jest zła), jak pokazano, będzie działać tylko z nazwanymi funkcjami - nie działałoby to w przypadku użycia w pytaniu.
Nowość w JavaScript Nie jestem pewien, czy zachowanie się zmieniło, ale rozwiązanie podane przez Jasona Buntinga (6 lat temu) nie będzie działać, jeśli to możliwe Funkcja nie jest zdefiniowana.
function isFunction(possibleFunction) {
return (typeof(possibleFunction) == typeof(Function));
}
Spowoduje to wygenerowanie ReferenceError: possibleFunction is not defined
błędu, gdy silnik spróbuje rozwiązać możliwy symbol Funkcja (jak wspomniano w komentarzach do odpowiedzi Jasona)
Aby uniknąć tego zachowania, możesz przekazać tylko nazwę funkcji, którą chcesz sprawdzić, czy istnieje. Więc
var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;
Ustawia zmienną na funkcję, którą chcesz sprawdzić, lub pusty obiekt, jeśli nie jest zdefiniowany, dzięki czemu unika się wyżej wymienionych problemów.
Próbować:
if (typeof(callback) == 'function')
if ('function' === typeof callback) ...
if(typeof Function === typeof callback)...
? :)
typeof
coś innego (być może „Funkcja” zamiast „funkcja”), z powodu nowej / innej implementacji JavaScript - wydaje się , że mniej prawdopodobne jest, że nowa / inna implementacja złamałaby typeof Function === typeof callback
kontrolę, ponieważ powinna być taka sama na poziomie semantycznym.
typeof(callback) == "function"
mogę zrobić
try{
callback();
}catch(e){};
Wiem, że istnieje akceptowana odpowiedź, ale nikt tego nie sugerował. Nie jestem do końca pewien, czy pasuje to do opisu idiomatic, ale działa we wszystkich przypadkach.
W nowszych silnikach JavaScript finally
można zamiast tego użyć.
typeof callback
tak zwykle używam .
accepted_types.indexOf(typeof value) !== -1
czy jest w zakresie typów. W tej sytuacji wyjątki byłyby moim zdaniem wygórowane.
Spróbuj tego:
callback instanceof Function
Jeśli używasz http://underscorejs.org , masz: http://underscorejs.org/#isFunction
_.isFunction(callback);
Jeśli callback()
wywołujesz nie tylko raz w funkcji, możesz zainicjować argument do ponownego użycia:
callback = (typeof callback === "function") ? callback : function(){};
Na przykład:
function something_cool(text, callback) {
// Initialize arguments
callback = (typeof callback === "function") ? callback : function(){};
alert(text);
if (text==='waitAnotherAJAX') {
anotherAJAX(callback);
} else {
callback();
}
}
Ograniczeniem jest to, że zawsze wykona argument wywołania zwrotnego, chociaż jest niezdefiniowany.
W przypadku funkcji globalnych możesz użyć tej zamiast eval
sugerowanej w jednej z odpowiedzi.
var global = (function (){
return this;
})();
if (typeof(global.f) != "function")
global.f = function f1_shim (){
// commonly used by polyfill libs
};
Możesz także użyć global.f instanceof Function
, ale afaik. wartość Function
będzie różna w różnych ramkach, więc będzie działać poprawnie tylko z aplikacją na pojedynczą ramkę. Dlatego zwykle używamy typeof
zamiast tego. Zauważ, że w niektórych środowiskach mogą również występować anomalie typeof f
, np. Przez MSIE 6-8 niektóre funkcje na przykładalert
miały typ „obiektowy”.
Za pomocą funkcji lokalnych możesz użyć tej z zaakceptowanej odpowiedzi. Możesz sprawdzić, czy funkcja jest lokalna czy globalna.
if (typeof(f) == "function")
if (global.f === f)
console.log("f is a global function");
else
console.log("f is a local function");
Aby odpowiedzieć na pytanie, przykładowy kod działa dla mnie bez błędów w najnowszych przeglądarkach, więc nie jestem pewien, z czym był problem:
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
Uwaga: użyłbym callback !== undefined
zamiast callback != null
, ale robią prawie to samo.
Większość, jeśli nie wszystkie poprzednie odpowiedzi, wywołują funkcję uboczną
tutaj najlepsza praktyka
masz funkcję
function myFunction() {
var x=1;
}
//direct way
if( (typeof window.myFunction)=='function')
alert('myFunction is function')
else
alert('myFunction is not defined');
//byString
var strFunctionName='myFunction'
if( (typeof window[strFunctionName])=='function')
alert(s+' is function');
else
alert(s+' is not defined');
Jeśli chcesz przedefiniować funkcje, najlepiej użyć zmiennych funkcyjnych, które są zdefiniowane w kolejności ich występowania, ponieważ funkcje są definiowane globalnie, bez względu na to, gdzie występują.
Przykład tworzenia nowej funkcji, która wywołuje poprzednią funkcję o tej samej nazwie:
A=function() {...} // first definition
...
if (typeof A==='function')
oldA=A;
A=function() {...oldA()...} // new definition
To zadziałało dla mnie
if( cb && typeof( eval( cb ) ) === "function" ){
eval( cb + "()" );
}
Rozwiązanie jednowierszowe:
function something_cool(text, callback){
callback && callback();
}