JavaScript wciąż mnie zaskakuje, a to kolejna instancja. Właśnie natrafiłem na kod, którego na początku nie rozumiałem. Debugowałem go i doszedłem do tego wniosku:
alert('a'['toUpperCase']()); //alerts 'A'
To musi być oczywiste, jeśli toUpperCase()
jest zdefiniowane jako element typu łańcuchowego, ale na początku nie miało to dla mnie sensu.
Tak czy siak,
- czy to działa, ponieważ
toUpperCase
należy do „a”? Czy dzieje się coś jeszcze za kulisami? kod czytałem posiada funkcję w następujący sposób:
function callMethod(method) { return function (obj) { return obj[method](); //**how can I be sure method will always be a member of obj** } } var caps2 = map(['a', 'b', 'c'], callMethod('toUpperCase')); // ['A','B','C'] // ignoring details of map() function which essentially calls methods on every // element of the array and forms another array of result and returns it
Jest to rodzajowa funkcja wywoływania DOWOLNYCH metod na DOWOLNYM obiekcie. Ale czy to oznacza, że określona metoda będzie już niejawnym członkiem określonego obiektu?
Jestem pewien, że brakuje mi poważnego zrozumienia podstawowej koncepcji funkcji JavaScript. Pomóż mi to zrozumieć.
javascript
function
Mahesha999
źródło
źródło
arr[5]
. Jeśli numery gdzie Nazwy identyfikatorów można użyć określenia: kropkaarr.5
.5['toString']()
.Odpowiedzi:
Aby to rozbić.
.toUpperCase()
jest metodąString.prototype
'a'
jest pierwotną wartością, ale zostaje przekonwertowana na jej reprezentację obiektuWięc
jest dostęp za pośrednictwem notacji nawiasowej na nieruchomości
toUpperCase
, zString.prototype
. Ponieważ ta właściwość odwołuje się do metody , możemy ją wywołać, dołączając()
źródło
foo.bar
ifoo['bar']
są równe, więc opublikowany kod jest taki sam jakPodczas używania
foo[bar]
(zwróć uwagę na brak cudzysłowów) nie używasz literalnej nazwy,bar
ale jakąkolwiek wartośćbar
zawiera zmienna . Zatem użyciefoo[]
notacji zamiastfoo.
pozwala na użycie nazwy właściwości dynamicznej.Rzućmy okiem na
callMethod
:Przede wszystkim zwraca funkcję, która przyjmuje
obj
jako argument. Po wykonaniu tej funkcji wywołamethod
ten obiekt. Zatem dana metoda musi istnieć albo naobj
sobie, albo gdzieś w swoim łańcuchu prototypów.W przypadku, gdy
toUpperCase
ta metoda pochodziString.prototype.toUpperCase
- byłoby głupotą mieć osobną kopię metody dla każdego istniejącego łańcucha.źródło
Możesz uzyskać dostęp do elementów dowolnego obiektu za pomocą
.propertyName
notacji lub["propertyName"]
notacji. Taka jest funkcja języka JavaScript. Aby upewnić się, że element członkowski znajduje się w obiekcie, po prostu sprawdź, czy jest zdefiniowany:źródło
Zasadniczo javascript traktuje wszystko jak Obiekt, a raczej każdy obiekt może być postrzegany jako słownik / tablica asocjacyjna. Funkcje / metody są definiowane dokładnie tak samo dla obiektu - jako pozycja w tej tablicy asocjacyjnej.
Zasadniczo odwołujesz się / wywołujesz (zwróć uwagę na właściwość „ () ”) obiektu „toUpperCase” obiektu „a” (w tym przypadku jest to ciąg znaków).
Oto kod na czubku głowy:
źródło
anyObject['anyPropertyName']
jest taki sam jakanyObject.anyPropertyName
wtedy, gdyanyPropertyName
nie ma problematycznych postaci.Zobacz Praca z obiektami z MDN.
toUpperCase
Metoda jest dołączony do typu String. Kiedy wywołujesz funkcję na pierwotnej wartości, tutaj'a'
jest ona automatycznie promowana do obiektu, tutaj Ciąg :Możesz zobaczyć, że funkcja istnieje po zalogowaniu
String.prototype.toUpperCase
.źródło
Więc w Javascript
objects
sąobjects
. To znaczy, że są tego rodzaju{}
. Właściwości obiektu można ustawić za pomocą jednego z poniższych:a.greeting = 'hello';
luba['greeting'] = 'hello';
. Oba sposoby działają.Pobieranie działa tak samo.
a.greeting
(bez cudzysłowu) jest'hello'
,a['greeting']
jest'hello'
. Wyjątek: jeśli właściwość jest liczbą, działa tylko metoda nawiasu. Metoda punktowa nie.Podobnie
'a'
jest z'toUpperCase'
obiektem, który w rzeczywistości jest funkcją. Możesz pobrać funkcję i wywołać ją później w dowolny sposób:'a'.toUpperCase()
lub'a'['toUpperCase']()
.Ale imo lepszy sposób na napisanie funkcji mapy byłby taki,
var caps = ['a','b','c'].map( function(char) { return char.toUpperCase(); } )
kto potrzebuje tej
callMethod
funkcji?źródło
Każdy obiekt JavaScript jest tabelą skrótów, dzięki czemu można uzyskać dostęp do jego członków, określając klucz. na przykład, jeśli zmienna jest łańcuchem, powinna mieć funkcję toUpperCase. Więc możesz to wywołać
więc, w wierszu in, możesz mieć poniżej
źródło
toUpperCase to standardowa metoda javascript: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/toUpperCase
Powodem tego
'a'['toUpperCase']()
jest to, że funkcja toUpperCase jest właściwością obiektu typu string'a'
. Możesz odwoływać się do właściwości obiektu za pomocąobject[property]
lubobject.property
. Składnia „a” „ToUpperCase” wskazuje, że odwołujesz się do właściwości „ToUppercase” obiektu „a”, a następnie wywołujesz ją ().źródło
Nie. Ktoś może przekazać przedmiot, który
toUpperCase
; lubtoUpperCase
która nie jest funkcjąW pierwszym przypadku zostanie zgłoszony błąd, ponieważ dostęp do właściwości, która nie istnieje, zwraca
undefined
i nie możemy wywoływaćundefined
funkcji.W drugim przypadku zostanie zgłoszony błąd, ponieważ ponownie nie możemy wywoływać funkcji innej niż funkcja.
Pamiętaj, że JavaScript jest językiem bardzo luźno pisanym. Sprawdzanie typu jest niewielkie lub nie występuje, chyba że będzie to konieczne. Pokazany kod działa w niektórych przypadkach, ponieważ w takich przypadkach przekazany obiekt ma właściwość o nazwie
toUpperCase
, która jest funkcją.Fakt, że
obj
argument nie ma odpowiednich właściwości, wcale nie przeszkadza JavaScript, że tak powiem. Przyjmuje podejście „poczekaj i zobacz” i nie zgłasza błędu, dopóki nie pojawi się rzeczywisty problem w czasie wykonywania.źródło
Prawie wszystko w javascript można traktować jako obiekt. W twoim przypadku sam alfabet działa jako obiekt łańcuchowy i
toUpperCase
można go wywoływać jako metodę. Nawiasy kwadratowe to tylko alternatywny sposób uzyskiwania dostępu do właściwości obiektu, a ponieważtoUpperCase
jest to metoda, dlatego()
obok['toUpperCase']
formowania potrzebny jest prosty nawias kwadratowy['toUpperCase']()
.'a'['toUpperCase']()
jest równa'a'.toUpperCase()
źródło
Należy tutaj zauważyć, że skoro Javascript jest językiem dynamicznym , każdy obiekt jest w zasadzie tylko uwielbioną mapą skrótu ( z kilkoma wyjątkami ). Do wszystkiego w obiekcie JavaScript można uzyskać dostęp na dwa sposoby - notację w nawiasach i notację kropkową.
Szybko przejrzę dwa zapisy odpowiadające na pierwszą część twojego pytania, a następnie przejdę do drugiej części.
Notacja w nawiasie
Ten tryb jest bardziej podobny do uzyskiwania skrótów i tablic w innych językach programowania. Możesz uzyskać dostęp do dowolnego komponentu (danych (w tym innych obiektów) lub funkcji) przy użyciu tej składni.
Właśnie to robisz w swoim przykładzie. Masz
'a'
, który jest ciągiem (a nie dosłownym znakiem, tak jak w języku takim jak C ++).Za pomocą notacji nawiasowej uzyskuje się dostęp do jej
toUpperCase
metody. Ale dostęp do niego wciąż nie wystarczy; po prostu wpisaniealert
, na przykład w JavaScript, nie wywołuje tej metody. To tylko proste stwierdzenie. Aby wywołać funkcję, musisz dodać nawias:alert()
pokazuje proste okno dialogowe zawierająceundefined
, ponieważ nie otrzymał żadnych parametrów. Możemy teraz wykorzystać tę wiedzę do odszyfrowania twojego kodu, który staje się:Co jest znacznie bardziej czytelne.
Właściwie dobrym sposobem na zrozumienie tego nieco lepiej jest uruchomienie następującego Javascript:
Wymaga to
alert
przekazując mu obiekt funkcji, równieżalert
bez również wykonanie drugiego wpisu. Pokazane (przynajmniej w Chrome 26) są następujące:Powołanie:
pokazuje dwa kolejne pola wiadomości zawierające
undefined
. Łatwo to wytłumaczyć:alert()
najpierw wykonywane jest wnętrze , pokazujeundefined
(ponieważ nie ma żadnych parametrów) i nic nie zwraca. Alarm zewnętrzny otrzymuje wartość zwracaną przez alert wewnętrzny - który jest niczym, a także pojawia sięundefined
w oknie komunikatu.Wypróbuj wszystkie skrzynki na jsFiddle!
Notacja kropkowa
Jest to bardziej standardowe podejście, które umożliwia dostęp do elementów obiektu za pomocą
.
operatora kropki ( ). Oto jak wyglądałby Twój kod w notacji kropkowej:O wiele bardziej czytelny. Kiedy więc powinniśmy używać notacji kropkowej, a kiedy notacji nawiasowej?
Porównanie
Główna różnica między tymi dwiema metodami jest semantyczna. Są też inne szczegóły, ale zajmę się nimi za chwilę. Najważniejsze jest to, co naprawdę chcesz zrobić - ogólna zasada polega na tym, że używasz notacji kropkowej dla dobrze ustalonych pól i metod, jakie posiada obiekt, oraz notacji nawiasowej, gdy faktycznie używasz swojego obiektu jako mapy hash .
Świetny przykład, dlaczego ta reguła jest tak ważna, można pokazać na przykładzie - ponieważ kod używa notacji nawiasowej w miejscu, w którym notacja kropkowa byłaby znacznie bardziej sensowna, utrudnia to odczytanie kodu. A to zła rzecz, ponieważ kod jest odczytywany wiele razy więcej niż jest napisany .
W niektórych przypadkach musisz użyć notacji nawiasowej, nawet jeśli bardziej sensowne jest użycie notacji kropkowej :
jeśli członek obiektu ma nazwę zawierającą co najmniej jedną spację lub dowolne inne znaki specjalne, nie można użyć notacji kropkowej:
foo.some method()
nie działa, alefoo["some method"]()
działa;jeśli potrzebujesz dynamicznie uzyskać dostęp do elementów obiektu, utkniesz także przy użyciu notacji nawiasowej;
Przykład:
Najważniejsze jest to, że powinieneś używać składni nawiasów, gdy używasz obiektu jako mapy skrótów (
foods["burger"].eat()
), a składni kropek, gdy pracujesz z „rzeczywistymi” polami i metodami (enemy.kill()
). Ponieważ Javascript jest językiem dynamicznym, granica między „rzeczywistymi” polami i metodami obiektu a „innymi” przechowywanymi danymi może być dość rozmyta. Ale dopóki nie pomieszacie ich w mylący sposób, wszystko powinno być w porządku.Teraz na resztę pytania (wreszcie!: P).
Nie możesz Spróbuj. Spróbuj wywołać
derp
ciąg. Pojawi się błąd w wierszach:Tak, w twoim przypadku musiałoby tak być. W przeciwnym razie kończy się błąd, o którym wspomniałem powyżej. Jednak nie mają do wykorzystania
return obj[method]();
wcallMethod()
funkcji. Możesz dodać własną funkcjonalność, która następnie zostanie użyta przez funkcję mapy. Oto zakodowana metoda, która zamienia wszystkie litery na wielkie:Kod w samouczku, który łączysz, używa funkcji częściowych . Same w sobie są trudną koncepcją. Czytanie więcej na ten temat powinno pomóc w wyjaśnieniu, niż mógłbym to uczynić.
Uwaga: jest to kod funkcji mapy używanej przez kod w pytaniu, źródło tutaj .
źródło
Jeśli pytasz, jak to naprawdę działa, tak to czytam. Ok, to jest prosta funkcja matematyczna. Aby to zrozumieć, musisz spojrzeć na tabelę ascii. Co przypisuje wartość liczbową każdej literze. Aby to ukryć, konkurencja używa po prostu instrukcji logicznej do ukrywania, więc na przykład Jeśli (ChcrValue> 80 && charValue <106) // Jest to zestaw małych liter, a następnie charValue = charValue - 38; // odległość między dolnym zestawem a górnym zestawem
to takie proste, tak naprawdę nie zadałem sobie trudu, aby wyszukać prawidłowe wartości, ale w zasadzie przenosiłem wszystkie małe litery na wielkie.
źródło
'a'['toUpperCase']()
działa. Ale nieporozumienie jest zrozumiałe, jeśli ktoś nie przeczytał pytania.text-transform: uppercase
dodano żadnych stylów , byłem na samym końcu, jak JS zdołał zmienić sprawę, wyjaśnił wątpliwości i nauczył się jednej lub dwóch rzeczy. wielkie dzięki.