Oryginalne pytanie:
JSHint narzeka, gdy mój JavaScript wywołuje funkcję, która jest zdefiniowana w dalszej części strony niż wywołanie jej. Jednak moja strona dotyczy gry i żadne funkcje nie są wywoływane, dopóki całość nie zostanie pobrana. Dlaczego więc funkcje kolejności pojawiają się w moim kodzie?
EDYCJA: Myślę, że mogłem znaleźć odpowiedź.
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
Jęczę w środku. Wygląda na to, że muszę spędzić KOLEJNY dzień na zamawianiu sześciu tysięcy wierszy kodu. Krzywa uczenia się z javascript nie jest wcale stroma, ale jest bardzo dłuuuuga.
javascript
function
jslint
jshint
Chris Tolworthy
źródło
źródło
Odpowiedzi:
tl; dr Jeśli nie dzwonisz, dopóki wszystko się nie załaduje, powinno być dobrze.
Edycja: przegląd obejmujący również niektóre deklaracje ES6 (
let
,const
): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_CheatsheetTo dziwne zachowanie zależy od
Oto kilka przykładów.
To z powodu czegoś, co nazywa się podnoszeniem !
Istnieją dwa sposoby definiowania funkcji: deklaracja funkcji i wyrażenie funkcji . Różnica jest irytująca i niewielka, więc powiedzmy trochę zła rzecz: jeśli piszesz to w ten sposób
function name() {}
, jest to deklaracja , a kiedy piszesz to jakovar name = function() {}
(lub anonimowa funkcja przypisana do zwrotu, takie rzeczy), to wyrażenie funkcyjne .Najpierw przyjrzyjmy się, jak obsługiwane są zmienne:
Teraz, jak obsługiwane są deklaracje funkcji :
Te
var
stwierdzenia „rzuca” na tworzenie sięfoo
na samym szczycie, ale jeszcze nie przypisać wartość do niego. Deklaracja funkcji jest następna w linii, a na końcu przypisywana jest wartośćfoo
.A co z tym?
Tylko deklaracja od
foo
przesuwa się do góry. Przypisanie następuje dopiero po wezwaniubar
, gdzie było przed całym podniesieniem.I wreszcie, dla zwięzłości:
A co z wyrażeniami funkcyjnymi ?
Podobnie jak zwykłe zmienne, najpierw
foo
zostanie ogłoszony w najwyższym punkcie zakresu, to jest przypisana wartość.Zobaczmy, dlaczego drugi przykład generuje błąd.
Jak widzieliśmy wcześniej, tylko tworzenie
foo
jest podnoszone, przypisanie pojawia się tam, gdzie pojawiło się w „oryginalnym” (niewniesionym) kodzie. Kiedybar
jest wywoływana, to jest wcześniejfoo
przypisywana wartość, więcfoo === undefined
. Teraz w treści funkcjibar
jest to tak, jakbyś robiłundefined()
, co powoduje błąd.źródło
Głównym powodem jest prawdopodobnie to, że JSLint wykonuje tylko jedno przejście do pliku, więc nie wie, że zdefiniujesz taką funkcję.
Jeśli użyłeś składni instrukcji funkcji
Właściwie nie ma żadnej różnicy w miejscu deklarowania funkcji (zawsze zachowuje się tak, jakby deklaracja była na początku).
Z drugiej strony, jeśli twoja funkcja została ustawiona jak zwykła zmienna
Musisz zagwarantować, że nie zadzwonisz przed inicjalizacją (w rzeczywistości może to być źródłem błędów).
Ponieważ zmiana kolejności ton kodu jest skomplikowana i może sama w sobie być źródłem błędów, sugerowałbym, abyś poszukał obejścia. Jestem prawie pewien, że możesz wcześniej podać JSLint nazwę zmiennych globalnych, więc nie narzeka na niezadeklarowane rzeczy.
Umieść komentarz na początku pliku
Możesz też użyć do tego pola tekstowego. (Myślę też, że możesz przekazać to w argumentach do wewnętrznej funkcji jslint, jeśli możesz się w to wtrącać.)
źródło
Zbyt wielu ludzi naciska na arbitralne zasady dotyczące pisania JavaScript. Większość zasad to bzdury.
Podnoszenie funkcji jest funkcją JavaScript, ponieważ jest dobrym pomysłem.
Kiedy masz funkcję wewnętrzną, która często jest użytecznością funkcji wewnętrznych, dodanie jej na początku funkcji zewnętrznej jest akceptowalnym stylem pisania kodu, ale ma tę wadę, że musisz przeczytać szczegóły, aby dostać się do czego zewnętrzna funkcja tak.
Powinieneś trzymać się jednej zasady w całym swoim kodzie, albo umieszczać prywatne funkcje jako pierwsze albo ostatnie w swoim module lub funkcji. JSHint jest dobry do wymuszania spójności, ale powinieneś ABSOLUTNIE dostosować .jshintrc do swoich potrzeb, NIE dostosowywać kodu źródłowego do zwariowanych koncepcji kodowania innych ludzi.
Jeden styl kodowania, którego możesz zobaczyć na wolności, którego powinieneś unikać, ponieważ nie daje żadnych korzyści, a jedynie możliwy ból związany z refaktoryzacją:
Właśnie tego należy unikać podczas podnoszenia. Po prostu naucz się języka i wykorzystaj jego mocne strony.
źródło
Podnoszone są tylko deklaracje funkcji, a nie wyrażenie funkcji (przypisanie).
źródło