Bug #065
🪲 Znajdź buga
const c = "constructor"
c[c][c](`console.log("It's alive!")`)()
Czy powyższy kod zadziała poprawnie i do konsoli zostanie zalogowany tekst It's alive!
?
🧪 Rozwiązanie
const c = "constructor"
c[c][c](`console.log("It's alive!")`)()
Tak! W kodzie nie ma buga, wszystko zadziała poprawnie.
Wyjaśnienia wymaga jednak kwestia, dlaczego ciąg znaków został wykonany.
W procesie tworzenia obiektów udział biorą funkcje nazywane konstruktorami.
W utworzonym obiekcie możemy dostać się do takiej funkcji uruchamiając na niej metodę o nazwie constructor
.
"".constructor
zwróci więc funkcję konstruktora obiektu ciągu znaków, czyli String
.
Przypisując ciąg znaków "constructor"
do stałej, a później używając jej w c[c][c]
, uzyskamy ten sam efekt co wywołując kod "constructor".constructor.constructor
.
Wiemy już, że konstruktorem ciągu znaków jest funkcja String
.
Idąc krok dalej, sprawdzamy jaki konstruktor bierze udział w procesie tworzenia obiektu ciągu znaków, czyli ekwiwalent wywołania String.constructor
.
Okazuje się, że zwrócony zostaje konstruktor funkcji, czyli Function
.
c[c][c]()
to więc finalnie to samo co Function()
.
W JavaScript do tworzenia funkcji możemy użyć funkcji konstruktora obiektu funkcji, przekazując jako argument ciąg znaków, który zostanie wykonany jako ciało funkcji.
Function(`console.log("It's alive!")`)
tworzy więc nową funkcję, której ciałem staje się przekazany ciąg znaków.
Działaniem przypomina to funkcję eval()
, która również przetwarza przekazany w argumencie ciąg znaków do postaci wykonywanego kodu.
Finalnie wykonujemy nowo utworzoną funkcję poprzez dodanie nawiasów na końcu Function(`console.log("It's alive!")`)()
.
Otrzymujemy ten sam efekt, który dało nam wywołanie\
c[c][c](`console.log("It's alive!")`)()
.
🎢 Plac zabaw
Otwórz edytor w nowym oknie📑 Linki
❤️ Podobają Ci się bugi JS?
Podziel się linkiem ze znajomymi:
https://codisity.pl/100-bugow-js