Widziałem teraz 2 metody określania, czy argument został przekazany do funkcji JavaScript. Zastanawiam się, czy jedna metoda jest lepsza od drugiej, czy też jest po prostu nieodpowiednia w użyciu?
function Test(argument1, argument2) {
if (Test.arguments.length == 1) argument2 = 'blah';
alert(argument2);
}
Test('test');
Lub
function Test(argument1, argument2) {
argument2 = argument2 || 'blah';
alert(argument2);
}
Test('test');
O ile mogę stwierdzić, oba skutkują tym samym, ale pierwszego użyłem tylko w produkcji.
Kolejna opcja, o której wspomniał Tom :
function Test(argument1, argument2) {
if(argument2 === null) {
argument2 = 'blah';
}
alert(argument2);
}
Zgodnie z komentarzem Juana lepiej byłoby zmienić sugestię Toma na:
function Test(argument1, argument2) {
if(argument2 === undefined) {
argument2 = 'blah';
}
alert(argument2);
}
javascript
arguments
Darryl Hein
źródło
źródło
argument2 || 'blah';
spowoduje „bla”, jeśliargument2
jestfalse
(!), A nie tylko, jeśli jest niezdefiniowane. Jeśliargument2
jest wartością logiczną, a funkcja jestfalse
dla niej przekazywana , linia ta zwróci „bla”, mimo żeargument2
jest poprawnie zdefiniowana .argument2
jest0
,''
albonull
.Odpowiedzi:
Istnieje kilka różnych sposobów sprawdzenia, czy argument został przekazany do funkcji. Oprócz dwóch wymienionych w (oryginalnym) pytaniu - sprawdzanie
arguments.length
lub używanie||
operatora do podania wartości domyślnych - można również jawnie sprawdzić argumenty zaundefined
pośrednictwemargument2 === undefined
lubtypeof argument2 === 'undefined'
jeśli jeden jest paranoiczny (patrz komentarze).Korzystanie z
||
operatorem stał się standardową praktyką - wszystkie fajne dzieciaki to zrobić - ale bądź ostrożny: Wartość domyślna zostanie wyzwolony jeśli analizuje schemat argumentfalse
, czyli może to być rzeczywiścieundefined
,null
,false
,0
,''
(lub czegokolwiek innego, dla któregoBoolean(...)
powracafalse
).Pytanie brzmi, kiedy należy użyć, które sprawdzanie, ponieważ wszystkie dają nieco inne wyniki.
Sprawdzanie
arguments.length
wykazuje zachowanie „najbardziej poprawne”, ale może nie być wykonalne, jeśli istnieje więcej niż jeden opcjonalny argument.Test na
undefined
następny jest „najlepszy” - „kończy się niepowodzeniem” tylko wtedy, gdy funkcja jest jawnie wywoływana zundefined
wartością, która najprawdopodobniej powinna być traktowana tak samo, jak pominięcie argumentu.Użycie
||
operatora może spowodować użycie wartości domyślnej, nawet jeśli podany zostanie prawidłowy argument. Z drugiej strony jego zachowanie może być pożądane.Podsumowując: używaj go tylko wtedy, gdy wiesz, co robisz!
Moim zdaniem użycie
||
jest również dobrym rozwiązaniem, jeśli istnieje więcej niż jeden opcjonalny argument i nie chcemy przekazać literału obiektu jako obejścia nazwanych parametrów.Inny fajny sposób na
arguments.length
podanie wartości domyślnych jest możliwy poprzez przejrzenie etykiet instrukcji switch:Ma to tę wadę, że intencja programisty nie jest (wizualnie) oczywista i używa „magicznych liczb”; dlatego może być podatny na błędy.
źródło
Jeśli używasz jQuery, jedną z przyjemnych opcji (szczególnie w skomplikowanych sytuacjach) jest użycie metody rozszerzającej jQuery .
Jeśli wywołasz funkcję, to w ten sposób:
Zmienna opcji wyglądałaby wtedy:
źródło
To jeden z niewielu przypadków, w których znajduję test:
działa całkiem nieźle i niesie prawidłową implikację składniową.
(Przy jednoczesnym ograniczeniu, że nie pozwolę na uzasadnioną wartość zerową, dla
argument2
której ma inne znaczenie; ale byłoby to naprawdę mylące).EDYTOWAĆ:
To jest naprawdę dobry przykład różnicy stylistycznej między językami luźno i mocno pisanymi; oraz opcja stylistyczna, którą zapewnia javascript w pikach.
Moje osobiste preferencje (bez krytyki w stosunku do innych preferencji) to minimalizm. Im mniej kod ma do powiedzenia, dopóki jestem spójny i zwięzły, tym mniej ktoś inny musi zrozumieć, aby poprawnie wywnioskować moje znaczenie.
Jedną z implikacji tej preferencji jest to, że nie chcę - nie uważam za użyteczne - układania wielu testów zależności typu. Zamiast tego staram się, aby kod oznaczał to, jak wygląda; i testuj tylko pod kątem tego, co naprawdę będę musiał przetestować.
Jednym z zaostrzeń, które dostrzegam w kodzie innych ludzi, jest potrzeba ustalenia, czy w szerszym kontekście oczekują, czy rzeczywiście trafią na przypadki, w których testują. Lub jeśli próbują przetestować wszystko, co możliwe, na szansę, że nie przewidują wystarczająco kontekstu. Co oznacza, że w końcu muszę je dokładnie wyśledzić w obu kierunkach, zanim będę mógł cokolwiek zmienić lub zmodyfikować. Myślę, że istnieje spora szansa, że mogliby przeprowadzić te różne testy, ponieważ przewidzieli okoliczności, w których będą potrzebne (i które zwykle nie są dla mnie oczywiste).
(Uważam, że to poważna wada w sposobie, w jaki ci ludzie używają dynamicznych języków. Zbyt często ludzie nie chcą rezygnować ze wszystkich testów statycznych i kończą je udawanie).
Widziałem to najbardziej rażąco w porównaniu obszernego kodu ActionScript 3 z eleganckim kodem javascript. AS3 może być 3 lub 4 razy większy od js, a podejrzewam, że niezawodność przynajmniej nie jest lepsza, tylko z powodu liczby (3-4X) podjętych decyzji w sprawie kodowania.
Jak mówisz, Shog9, YMMV. :RE
źródło
Istnieją znaczne różnice. Ustawmy kilka przypadków testowych:
Przy pierwszej opisanej metodzie tylko drugi test użyje wartości domyślnej. Druga metoda będzie domyślnie wszystko ale pierwszy (jak JS przekonwertuje
undefined
,null
,0
, i""
do wartości logicznejfalse
. A jeśli było użyć metody Toma, tylko czwarta próba użyje domyślnego!Wybór metody zależy od zamierzonego zachowania. Jeśli wartości inne niż
undefined
są dozwoloneargument2
, prawdopodobnie będziesz potrzebować pewnej odmiany pierwszego; jeśli pożądana jest niezerowa, niepusta, niepusta wartość, wówczas druga metoda jest idealna - w rzeczywistości często stosuje się ją do szybkiego wyeliminowania tak szerokiego zakresu wartości z rozważań.źródło
źródło
W ES6 (ES2015) możesz użyć parametrów domyślnych
źródło
"default value"
i sprawdzanie, czy wartość jest rzeczywiście"default value"
.Przepraszam, wciąż nie mogę komentować, więc aby odpowiedzieć na odpowiedź Toma ... W javascript (undefined! = Null) == false W rzeczywistości ta funkcja nie będzie działać z „null”, powinieneś użyć „undefined”
źródło
Dlaczego nie skorzystać z
!!
operatora? Ten operator, umieszczony przed zmienną, zamienia ją na wartość logiczną (o ile dobrze rozumiem), więc!!undefined
i!!null
(a nawet!!NaN
, co może być całkiem interesujące) powrócifalse
.Oto przykład:
źródło
Podejście do wykrywania argumentów może być wygodne, wywołując funkcję za pomocą obiektu właściwości opcjonalnych:
źródło
Istnieje również trudny sposób stwierdzenia, czy parametr jest przekazywany do funkcji, czy nie . Spójrz na poniższy przykład:
Oznacza to, że jeśli wartość parametru
value
nie występuje / nie została przekazana - ustaw ją na 0.Całkiem fajne, huh!
źródło
value
jest równoważnefalse
, ustaw na 0”. Jest to subtelne, ale bardzo ważne rozróżnienie.true
ifalse
są poprawnymi wartościami, i możesz chcieć mieć trzecie zachowanie, gdy parametr nie zostanie w ogóle przekazany (szczególnie jeśli funkcja ma więcej niż jeden parametr).Czasami możesz również chcieć sprawdzić typ, szczególnie jeśli używasz funkcji jako getter i setter. Następujący kod to ES6 (nie będzie działał w EcmaScript 5 lub starszym):
źródło
Ponieważ tablice dziedziczą
Object.prototype
. Zastanów się ⇑, aby uczynić świat lepszym.źródło
fnCalledFunction (Param1, Param2, window.YourOptionalParameter)
Jeśli powyższa funkcja jest wywoływana z wielu miejsc i masz pewność, że pierwsze 2 parametry są przekazywane z każdego miejsca, ale nie jesteś pewien co do trzeciego parametru, możesz użyć okna
Window.param3 obsłuży, jeśli nie jest zdefiniowane w metodzie wywołującej.
źródło