Mam daną funkcję, która pobiera, oprócz innych argumentów, dwa opcjonalne argumenty, które mogą być funkcjami. Oba muszą być opcjonalne, jeden będzie funkcją, a drugi będzie boolowskim lub funkcją zwracającą wartość logiczną.Sprawdź, czy funkcja JavaScript zwraca się bez jej wykonywania?
// Obj.func(variable, String[, Object][, Boolean||Function][, Function]);
Obj.func = function(other, assorted, args, BoolOrFunc, SecondFunc) {
// execution
};
Obj.func(
[
'some',
'data'
],
'of varying types',
{
and: 'some optional arguments'
},
function() {
if(some condition) {
return true;
}
return false;
},
function() {
// do things without returning
}
);
To jest moje pragnienie, że obie funkcje (i kilka innych argumentów, jeśli ma to znaczenie) są opcjonalne, co oznacza, że mam kod w funkcji, aby określić, które argumenty użytkownik zamierza wykorzystać.
Niestety, ponieważ obie mogą być funkcjami i mogą być określone bezpośrednio w wywołaniu funkcji, nie mogę po prostu użyć warunkowych typeof
lub instanceof
. Jednak od pierwszej funkcji, jeśli taka istnieje, zostanie zawsze zwróci wartość logiczną (a druga funkcja nie wróci w ogóle), jeden pomysł miałem byłoby sprawdzić jego wartość powrotu:
if(typeof BoolOrFunc === 'boolean'
|| (typeof BoolOrFunc === 'function' && typeof BoolOrFunc() === 'boolean')) {
// BoolOrFunc is either a boolean or a function that returns a boolean.
// Handle it as the intended argument.
} else {
// Otherwise, assume value passed as BoolOrFunc is actually SecondFunc,
// and BoolOrFunc is undefined.
}
ten działa w zasadzie; jednak uruchamianie typeof BoolOrFunc()
wykonuje funkcję, która powoduje problem, jeśli funkcja nie tylko zwraca wartość boolowską: to znaczy, że funkcja przekazana jako BoolOrFunc
jest faktycznie oznaczona jako SecondFunc
. SecondFunc
, w tym przypadku jest czymś w rodzaju funkcji wywołania zwrotnego i może wykonywać akcje, w tym modyfikacje DOM, których nie chcę wykonywać natychmiast.
Z tego powodu moje pytanie brzmi: Czy istnieje sposób, aby sprawdzić, czy funkcja zwraca bez wykonywania go?
Jedno miałem uważane było zadzwonić BoolOrFunc.toString()
, a następnie wykonać wyszukiwanie wyrażenia dla wartości zwracanej, coś na wzór ...
if(typeof BoolOrFunc === 'boolean'
|| (typeof BoolOrFunc === 'function'
&& BoolOrFunc.toString().search(/return (true|false);/) !== -1)) {
// BoolOrFunc is either a boolean or contains a return string with a boolean.
// Handle it as the intended argument.
}
Zauważ, że powyższy kod może nie działać jak napisano: Nie zbudowałem dla niego przypadku testowego, ponieważ, cóż, wydaje się wyjątkowo nieskuteczne i potencjalnie niewiarygodne, i pomyślałem, że ktoś tutaj może mieć bardziej eleganckie rozwiązanie mojego dylematu. To powiedziawszy, doszedłem do wniosku, że uwzględnię to do celów dyskusji.
Jako niepotwierdzonych marginesie, to jest dość blisko do powstrzymania problem (http://en.wikipedia.org/wiki/Halting_problem), który jest nierozstrzygalny nad Maszyna Turinga. :) – lexicore
Heh, poruszysz dobry punkt. Prawdopodobnie oczekuję zbyt wiele od JS. : P – Meshaal
Dla przypadku, który użytkownicy nazywają formularzem, który podaje wartość logiczną i funkcję, która zwraca wartość logiczną, można zamiast tego wymagać podania argumentów owiniętych w obiekcie, np. 'Obj.func (myvar, mystring, myobj, {boolarg: true, funcarg: my_func_that_returns_bool}); 'lub coś w tym stylu, aby było jednoznaczne co to jest. Następnie użytkownik musi upewnić się, że 'my_func_that_returns_bool' robi to, co twierdzi – Brandin