Co się stanie, jeśli nie przekażę parametru w funkcji JavaScript?


88

Jestem nowy w świecie Javascript i majstruję przy pisaniu bardzo podstawowych funkcji i przez przypadek natknąłem się na poniższy przykład i nie jestem pewien, dlaczego działa, gdy nie przekazuję parametru, gdy funkcja tego wymaga.

Przykładowa funkcja

function myfunction(x) {
    alert("This is a sample alert");
}

Teraz, gdy wywołuję funkcję myfunction();, pojawia się alert. Dlaczego mogę wywołać funkcję bez żadnych błędów lub ostrzeżeń, gdy nie przekazałem parametru?

EDYTOWAĆ

Nie spodziewałem się tylu wspaniałych odpowiedzi i nie jestem jeszcze w stanie powiedzieć, która odpowiedź jest najlepsza, więc mogę poprosić ludzi o zaproponowanie najlepszej odpowiedzi i nagrodzę tę osobę za akceptację.



1
Nie ma przeciążenia opartego na sygnaturach funkcji w JS, więc naprawdę nie ma znaczenia, ile parametrów funkcja „oczekuje”. Możesz nawet przekazać parametry, których funkcja nie jest zdefiniowana, i po prostu użyć argumentów słów kluczowych, aby je pobrać.
scrappedcola

@scrappedcola - Co masz na myśli, mówiąc o przeciążaniu, a także przekazywaniu parametrów, których funkcja nie jest zdefiniowana? Czy możesz podać przykłady?
PeanutsMonkey

2
@PeanutsMonkey. Miał na myśli, że nie możesz mieć dwóch funkcji: function foo(x){...}i function foo(x,y,z){...}możesz mieć tylko jedną funkcję dla każdego imienia.
gdoron wspiera Monikę

2
@PeanutsMonkey. Tak, nie możesz mieć function overloadingw js, ale masz inne sposoby, aby z tego kpić.
gdoron wspiera Monikę

Odpowiedzi:


111

Nic się nie stanie - co oznacza, że ​​nie otrzymasz błędu ani ostrzeżenia, ponieważ przekazanie parametrów w javascript jest opcjonalne.
Wszystkie parametry, które nie zostały „dostarczone”, będą miały undefinedwartość .

function foo(x, y, z){
    //...
}

foo(1);

Wewnątrz foofunkcji teraz:

function foo(x, y, z){
    x === 1
    y === undefined
    z === undefined
}

Możesz nawet przekazać więcej argumentów, takich jak:

foo(1,2,3,4,5,7); // Valid!

Możesz poznać ilość parametrów dostarczonych przez arguments.lengthfunkcję z wnętrza funkcji.

function foo(x, y, z) {
    console.log('x value: ' + x);
    console.log('y value: ' + y);
    console.log('z value: ' + z);
    console.log('Arguments length: ' + arguments.length);
}
console.log('Zero parameters');
foo();
console.log('Four parameters');
foo(1, 2, 3, 4);

Przykład przydatnej funkcji obsługującej dowolną ilość parametrów:

function max() {
    var maxValue = arguments[0];
    for (var i = 1; i < arguments.length; i++) {
        if (maxValue < arguments[i]) {
            maxValue = arguments[i];
        }
    }
    return maxValue;
}

alert(max(1, 5, 7, 2, 88, 32, 44));


Dzięki za demo na żywo. Nie spodziewałem się tylu dobrych odpowiedzi. Czyli jeśli mam taką funkcję jak function myfunction (a,b){}i przekazałem wartości mojafunkcja (1,2,3,4,5), przyjmuję, że nadal jest ważna? Czy spodziewasz się, że wystąpi jakieś ostrzeżenie lub błąd?
PeanutsMonkey

Przepraszam, czy mógłbyś wyjaśnić, co console.logrobi polecenie , a także arguments.length?
PeanutsMonkey

@PeanutsMonkey. Ważny! bez ostrzeżenia bez błędu, przyda się nawet, za chwilę dam demo.
gdoron wspiera Monikę

1
@PeanutsMonkey. Działa również z IE, jeśli masz zainstalowaną konsolę programisty, myślę, że jest ona instalowana domyślnie z IE8 +. Nie rozumiem, o czym pisałeś alert.
gdoron wspiera Monikę

1
@PeanutsMonkey. 1. Nie możesz mieć kodu po returnjego zignorowaniu. 2. nie otrzymasz błędów ani ostrzeżeń. Zobacz DEMO
gdoron wspiera Monikę

9

Wszystkie argumenty w funkcjach JavaScript są opcjonalne (czytaj „luźno wpisane”).

Funkcje JavaScript można wywołać z dowolną liczbą argumentów, niezależnie od liczby argumentów podanych w definicji funkcji. Ponieważ funkcja jest wpisana luźno, nie ma możliwości zadeklarowania typu argumentów, których oczekuje, i dozwolone jest przekazywanie wartości dowolnego typu do dowolnej funkcji. Gdy funkcja jest wywoływana z mniejszą liczbą argumentów niż zadeklarowano, dodatkowe argumenty mają wartość niezdefiniowaną.

Możesz odwołać się do argumentów funkcji w ramach funkcji, używając nazwanych zmiennych argumentów lub obiektu arguments. Ten obiekt zawiera wpis dla każdego argumentu przekazanego do funkcji, indeks pierwszego wpisu zaczyna się od 0. Na przykład, jeśli funkcja ma przekazane trzy argumenty, możesz odwołać się do argumentu w następujący sposób:

arguments[0]
arguments[1]
arguments[2]
  • JavaScript - The Definitive Guide, 5. wydanie

7

Tak właśnie działa JavaScript. Parametry są opcjonalne i będą miały w funkcji wartość „undefined”, która nie jest wartością, jeśli ich brakuje w wywołaniu funkcji.

Przez „opcjonalne” mam na myśli tylko to: wywołanie dowolnej funkcji wiąże się z dowolnie długą listą parametrów. Nie musi istnieć związek między liczbą parametrów przekazanych do funkcji a zadeklarowaną liczbą . A zatem najlepszy sposób, aby przemyśleć tę deklarację:

function x(a, b, c) {
  // ...
}

polega na tym, że deklarujesz funkcję i wiążesz nazwę „a” z pierwszym parametrem, „b” z drugim i „c” z trzecim. Nie ma jednak żadnej gwarancji, że którykolwiek z nich zostanie faktycznie powiązany z wartością w dowolnym późniejszym wywołaniu funkcji.

W ten sam sposób można zdefiniować funkcję bez żadnych parametrów, a następnie „znaleźć” je za pomocą argumentsobiektu:

function noArgs() {
  var a = arguments[0], b = arguments[1], c = arguments[2];
  // ...
}

Więc to nie jest dokładnie to samo, co pierwsza funkcja, ale jest blisko na większość praktycznych sposobów.

Wartość „undefined” w JavaScript jest wartością, ale jej semantyka jest dość nietypowa w przypadku języków. W szczególności nie jest to dokładnie to samo, co nullwartość. Również „niezdefiniowany” sam w sobie nie jest słowem kluczowym; to tylko pół-specjalna nazwa zmiennej!


Czy mógłbyś szerzej wyjaśnić, co masz na myśli, optionalmówiąc o wartości „nie jest to naprawdę wartość” undefined?
PeanutsMonkey

@PeanutsMonkey - Jeśli zmienna nie jest podana, to będzie undefined.
Derek 朕 會 功夫

@Pointy - co masz na myśli mówiąc, że nie ma gwarancji, że którykolwiek z zadeklarowanych parametrów zostanie faktycznie powiązany z wartością?
PeanutsMonkey

1
@PeanutsMonkey JavaScript to język dynamiczny . Podczas wywoływania funkcji nie jest ważna deklaracja funkcji, w tym liczba parametrów. W ten sposób możesz zadeklarować funkcję z dowolną liczbą parametrów, ale nie nakłada to żadnych ograniczeń na liczbę parametrów faktycznie przekazywanych podczas wywoływania funkcji. (W ten sposób jest to coś w rodzaju C, przynajmniej C w dawnych czasach). Tak więc, jeśli zadeklarujesz parametr i wywołanie zostanie wykonane bez dostarczonej wartości parametru, parametr będzie undefined.
Pointy

3

JavaScript nie ma domyślnych wartości parametrów funkcji, jak w innych językach. Możesz więc przekazać dowolną liczbę lub mniej argumentów.

Jeśli nie przekażesz wartości, parametr to undefined.

function myfunction(x) {
    alert(x);
}

myfunction(); // alerts undefined
myfunction(1); // alerts 1
myfunction(1,2,3); // alerts 1

Jeśli przekażesz więcej parametrów niż w podpisie, możesz użyć arguments.

function myfunction(x) {
    alert(x);
    console.log(arguments);
}

myfunction(1,2,3); // alerts 1, logs [1,2,3]

Dzięki. Zamiast zamieszczać posty krzyżowe, czy mógłbyś zobaczyć mój przykład, który undefined
podałem

@PeanutsMonkey: Hę? Jaki masz problem?
Rocket Hazmat

Nie jest to problem per se. Miałem na myśli moje pytanie uzupełniające do Davida dotyczące przekazywania większej liczby parametrów, które zawarłeś w swojej odpowiedzi. To, czego nie całkiem rozumiem, to co masz na myśli logs? Gdzie to rejestruje?
PeanutsMonkey

1
@PeanutsMonkey: rejestruje to w „konsoli JavaScript”. W większości przeglądarek możesz nacisnąć F12lub, Ctrl+Shift+Jaby się do niego dostać.
Rocket Hazmat

1
Pierwsze zdanie jest nieaktualne od ES2015 ...
Heretic Monkey

2

Możesz także podać więcej argumentów niż tylko jeden wymieniony w funkcji

myFunction(1,2,3,4,5,6,7,'etc');

Możesz użyć argumentswłaściwości, która jest tablicą, aby wyświetlić podane argumenty.


@albert argumenty nie są tablicami w postaci tablicy, jak obiekt patrz
Mahi

1

Ponieważ nie ma błędu, dopóki funkcja nie spodziewa się, że będzie w stanie pracować z parametrem, który masz przekazać.

Na przykład:

function myfunction(x) {
    return x*2;
}

Zgłosiłby błąd; aczkolwiek prawdopodobnie tylko a NaN(w tym przypadku) lub a variable is undefined.


Okay, tak długo, jak nie odwołuję się do parametru w funkcji, nie otrzymam błędu? Czy to prawda?
PeanutsMonkey

Teraz, jeśli rozwinę przykład, który podasz, tj., function myfunction(a,b) { var calc = a+b; return;}A następnie wywołam funkcję, document.write(myfunction(1.2));dlaczego nadal otrzymuję wartość, undefinedmimo że przekazuję parametr?
PeanutsMonkey

1
Ponieważ nic nie zwracasz. W swoim przykładzie musisz jawnie zwrócić wartość: albo return calc; lub return a+b;(oczywiście jako ostatnia linia; i ta ostatnia returnzamiast var calc).
David mówi, że przywróć Monikę

Więc masz na myśli, że nie muszę deklarować zmiennej, jeśli to zrobię return a+b;?
PeanutsMonkey

@PeanutsMonkey - Możesz przeczytać więcej return tutaj .
Derek 朕 會 功夫

0

Jeśli pominiesz argument, jego wartość będzie wynosić undefined. Umożliwia to dość łatwe tworzenie parametrów opcjonalnych.

Inną cechą jest możliwość zdefiniowania funkcji bez parametrów i pomyślnego wywołania jej z argumentami, korzystając z argumentsobiektu. Pozwala to łatwo tworzyć tablice argumentów o zmiennej długości.


0

W console.log javascript wewnątrz funkcji podaje dane wyjściowe undefined dla nieprzekazanych parametrów, ale poza funkcją podaje niezdefiniowany błąd, ponieważ wewnątrz funkcji przeglądarki jawnie deklarują zmienną. Np

console.log(x) 

daje VM1533: 1 Uncaught ReferenceError: x nie jest zdefiniowane, podczas gdy

function test(x) {
console.log(x)
}
test(); 

daje undefined. Dzieje się tak, ponieważ funkcja test () jest przepisywana przez przeglądarkę jako:

function test(x) {
    var x;
    console.log(x)
    }

Inny przykład : -

var x =5 ;
function test(x) {
console.log(x)
}
test(); 

jest nadal niezdefiniowana, gdy funkcja staje się

function test(x) {
    var x;
    console.log(x)
    }

Alert w poniższym przykładzie da undefined: -

    var x =5;
    function test() {
    alert(x);
    var x =10;
    }

test(); 

Powyższa funkcja stanie się: -

 function test() {
    var x;
    alert(x);
    x =10;
    }

Zakres zmiennej javascript wewnątrz funkcji to zakres na poziomie funkcji, a nie na poziomie bloku. Np

function varScope() {

for(var i = 0; i < 10; i++){
    for(var j = 0; j < 5; j++){}
        console.log("j is "+j)
    }
    console.log("i is "+i);


}
varScope();

da wynik jako:

j is 5 
i is 10

Znowu funkcja stała się następująca: -

  function varScope() {
    var i;
    var j;
    for(i = 0; i < 10; i++){
        for(j = 0; j < 5; j++){}
            console.log("j is "+j)
        }
        console.log("i is "+i);
    }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.