Napisałem następujący skrypt, aby zobaczyć, co się dzieje, gdy zmienna i funkcja, do której jest przypisana funkcja, mają zderzenie nazw:
var f = function() {
console.log("Me original.");
}
function f() {
console.log("Me duplicate.");
}
f();
Wynik, który otrzymuję, to „Mój oryginał”. Dlaczego nie wywołano drugiej funkcji?
Ponadto, jeśli zmienię swoje pierwotne przypisanie na var f = new function() {
, otrzymam „Mój oryginał”, a po nim stwierdzenie TypeError object is not a function
. Czy ktoś może wyjaśnić?
javascript
function
ankush981
źródło
źródło
Odpowiedzi:
Deklaracje funkcji są podnoszone (przenoszone na górę) w JavaScript. Chociaż niepoprawny pod względem kolejności analizowania, kod, który masz, jest semantycznie taki sam jak poniższy, ponieważ deklaracje funkcji są podnoszone:
Która z kolei, z wyjątkiem nazwy funkcji, jest taka sama jak:
Co z kolei ze względu na zmienne podnoszenie jest tym samym, co:
Co wyjaśnia, co otrzymujesz, nadpisujesz funkcję. Mówiąc bardziej ogólnie,
var
w JavaScript dozwolone są wielokrotne deklaracje -var x = 3; var x = 5
jest to całkowicie legalne. W nowym standardzie ECMAScript 6let
zabraniają tego stwierdzenia.Ten artykuł autorstwa @kangax wykonuje fantastyczną robotę w demistyfikacji funkcji w javascript
źródło
function f()
dovar f = function()
tak dużo? Czy nazwy podnoszenia i funkcji to naprawdę jedyna różnica?f
są podnoszone, a"Me Original"
wersja jest podnoszona później , każda z nich jest przenoszona na górę, ale w tej samej kolejności. Dodam tylko, że ogólnie nie należy nazywać kilku funkcji tak samo :)var
dwukrotnie nadać tej samej nazwy w tym samym zakresie.Jeśli nie wygląda na to, że ktoś odpowiedział na Twoje dodatkowe pytanie, odpowiem na nie tutaj, chociaż generalnie powinieneś zadawać dodatkowe pytania jako osobne pytania.
Zapytałeś, dlaczego to:
wydrukuje „Ja oryginał”. a następnie błąd.
To, co się tutaj dzieje, polega na tym, że
new
powoduje, że funkcja jest używana jako konstruktor. Więc jest to równoważne z następującym:A dzięki funkcji podnoszenia, którą wyjaśnił Benjamin, powyższe jest zasadniczo równoważne z tym:
To wyrażenie:
powoduje konstruowanie i przypisywanie nowego obiektu
f
przy użyciu anonimowej funkcji jako konstruktora. „Ja oryginalny”. jest drukowany w trakcie wykonywania konstruktora. Ale skonstruowany obiekt sam w sobie nie jest funkcją, więc kiedy to w końcu się wykona:f
pojawia się błąd, ponieważ nie jest funkcją.źródło
Wybacz mi, jeśli to niewłaściwy sposób dodawania punktu. Nie byłem tu zbyt często i przyjąłbym konstruktywne wskazówki i / lub krytykę.
Odpowiedź Benjamina doskonale odpowiada na pytanie OP, ale chciałbym dodać jedną poprawkę, która da nam pełną prezentację podnoszenia i jego osobliwości.
Jeśli zaczniemy oryginalny kod od wezwania do
f
:Wynik będzie wtedy:
Powodem jest to,
var
afunction
oświadczenia są podnoszone na nieco inne sposoby.Na
var
tej deklaracji jest przesuwana do góry bieżącego Zakres *, ale każde zadanie nie jest podniesiona. Jeśli chodzi o wartość zadeklarowanej zmiennej, jest ona niezdefiniowana, dopóki nie zostanie osiągnięta pierwotna linia przypisania.W przypadku
function
instrukcji podnoszona jest zarówno deklaracja, jak i definicja. Wyrażenia funkcyjne użyte wvar f = function() {...
konstrukcji nie są podnoszone.Więc po podniesieniu wykonanie wygląda tak, jakby kod był:
* Cały zakres JavaScript jest leksykalny lub funkcjonalny, ale wydawało się, że użycie słowa f w tym momencie byłoby po prostu pomieszane.
źródło