JSF ** k tylko z 5 symbolami?

47

To nie jest wyzwanie, ale pytanie, doszedłem do wniosku, że z tego powodu

Tematy niezwiązane z wyzwaniem, które są związane z rozwiązywaniem zagadek programistycznych lub szczególnym rodzajem wyzwania, są również na temat.

Teraz przejdź do pytania:

Czy można napisać kod JavaScript zawierający tylko 5 liter? JSFuck już to robi z 6 symbolami, !+[]()ale zastanawiam się, czy !postać jest potrzebna.

JSFuck działa z kombinacją rzutowania na ciąg znaków (przez dodanie pustej tablicy), rzutowania na liczbę (przez napisanie + na początku) i rzutowania na wartość logiczną przez negację. Na przykład:

[]        \\ Empty array
+[]       \\ Cast to number -> 0
!+[]      \\ Negate -> true
!+[]+[]   \\ Cast to string -> "true"

Z tego ciągu możemy wyodrębnić wszystkie litery za pomocą nawiasów kwadratowych z cyfrą w środku, a dowolną liczbę można utworzyć, dodając razem prawdę tyle razy.

W ten sposób można znaleźć wiele liter i połączyć je w łańcuchy. Najważniejszym ciągiem, który można utworzyć, jest "constructor"to, że można go użyć do uzyskania Functiondowolnej funkcji, a tego obiektu można użyć do wykonania ciągów jako JavaScript:

[]["find"]                          \\ the function Array.prototype.find
[]["find"]["constructor"]           \\ the Function object
[]["find"]["constructor"](string)() \\ same as eval(string)

Jak widać, !ma 2 zastosowania tutaj:

  • Tworzenie liczb w celu wybrania liter z ciągów znaków.
  • Przesyłanie na boolean, aby uzyskać "true"i "false".

Pierwszy z tych 2 można również wykonać przy użyciu modułu ++inkrementora, a nie bezpośrednio 0, ale można go użyć na elementach wewnątrz tablicy:

+[]          \\ 0
[+[]]        \\ [0]
[+[]][+[]]   \\ [0][0] -> 0
++[+[]][+[]] \\ ++[0][0]-> 1
++[[]][+[]]  \\ also works because ++ casts to number

Dzięki temu wszystkie liczby można tworzyć bez !.

Drugi jest trudniejszy. Znaczenie "true"i "false"leży w literach "r"i "s", które oba pojawiają się w "constructor". Mam już znaleźć wszystkie kolejne litery "constructor"za pomocą "undefined", "Infinity", "NaN"i oddając funkcje ciągów.

Tak więc ostateczne pytanie: (jak) możesz tworzyć booleany, litery "r"i "s"JavaScript, używając tylko +[]()?

List "l"może również pomóc. Można go uzyskać w formie, nullale nie udało mi się uzyskać tej wartości za pomocą tych 5 symboli. Można go na przykład użyć do otrzymania logicznych wartości, jeśli mamy już "s":

[]["includes"]()       \\ false
[+[]]["includes"](+[]) \\ true

Pismo "l"i "k"razem daje dostęp do "r":

([]+[])["link"]() \\ "<a href="undefined"></a>"

Każdy sposób uzyskania wartości logicznej nulllub dowolnej litery r s l kbyłby bardzo przydatny!

Biblioteka tego, co mamy:

Array.prototype.find: [] [(([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + ( ++ [[]] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []])])]

Nieskończoność: + ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ [[]] [+ []]) + (+ + [[]] [+ []]) + (++ [[]] [+ []])]) + (++ [[]] [+ []] + []) + (+ []) + (+ []) + (+ []))

NaN: + [] [[]]

nieokreślony: [][[]]

0: + []

1: ++ [[]] [+ []]

2: (++ [[]] [+ []]) + (++ [[]] [+ []])

3: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

4: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[] ] [+ []])

5: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[] ] [+ []]) + (++ [[]] [+ []])

6: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

7: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

8: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

9: (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])

a: (+ [] [[]] + []) [++ [[]] [+ []]]

c: ([] [(([[] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ [ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]

d: ([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []])]

e: ([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [ + []])]

f: ([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [ + []]) + (++ [[]] [+ []])]

i: ([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [ + []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]

n: ([] [[]] + []) [++ [[]] [+ []]]

o: ([] [(([[] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ [ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]

t: (+ ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ [[]] [+ []]) + ( ++ [[]] [+ []]) + (++ [[]] [+ []])]) + (++ [[]] [+ []] + []) + (+ [] ) + (+ []) + (+ [])) + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ [] ])]

u: ([] [[]] + []) [+ []]

v: ([] [(([[] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ [ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]))]

y: (+ ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ [[]] [+ []]) + ( ++ [[]] [+ []]) + (++ [[]] [+ []])]) + (++ [[]] [+ []] + []) + (+ [] ) + (+ []) + (+ [])) + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ [] ]) + (++ [[]] [+ []])]

I: (+ ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ [[]] [+ []]) + ( ++ [[]] [+ []]) + (++ [[]] [+ []])]) + (++ [[]] [+ []] + []) + (+ [] ) + (+ []) + (+ [])) + []) [+ []]

N: (+ [] [[]] + []) [+ []]

„”: ([] [(([[] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (+ + [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + [ ]) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [+ (++ [[]] [+ [] ] + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (+ + [[]] [+ []]) + (++ [[]] [+ []]))]]

(: ([] [(([[] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ [ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [+ (++ [[]] [+ []] + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]))]]

): ([] [(([[] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ [ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [+ (++ [[]] [+ []] + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])))]

{: ([] [(([[] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ [ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [+ (++ [[]] [+ []] + [] + ((++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])))]

}: ([] [(([[] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ [ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [ []] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + [] ) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [+ ((++ [[]] [+ [] ]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + [] + ((++ [[]] [+ []]) + ( ++ [[]] [+ []])))]

.: (+ (++ [[]] [+ []] + [] + (++ [[]] [+ []]) + ([] [[]] + []) [(++ [ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])] + (++ [[]] [+ [] ] + [] + (+ []) + (+ []))) + []) [++ [[]] [+ []]]

,:[[]] [([] [(([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + ( ++ [[]] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [(++ [[]] [+ [ ]]) + (++ [[]] [+ []]) + (++ [[]] [+ []])] + ([] [(([] [[]] + []) [ (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [ + []])]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + ( ++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[] ] + []) [++ [[]] [+ []]]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []])])] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [ []] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []] )] + ([] [[]] + []) [++ [[]] [+ []]] + ([] [(([] [[]] + []) [(++ [ ]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) ]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[] ] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + (([] [[]] + []) [++ [[]] [+ []]]) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [ + []])])] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])] + (+ [] [[]] + []) [++ [[]] [+ []]] + (+ ((++ [[]] [+ []] + []) + (([] [[]] + []) [(++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []])]) + ( ++ [[]] [+ []] + []) + (+ []) + (+ []) + (+ [])) + []) [(++ [[]] [+ [] ]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[]] [+ []]) + (++ [[ ]] [+ []]) + (++ [[]] [+ []])]] ([[]]) + []
Jens Renders
źródło
Jest to bardzo ściśle powiązane z codegolf.stackexchange.com/q/11690/194 , a gdyby na to pytanie udzielono odpowiedzi JS, głosowałbym za jego zamknięciem. W tej chwili odpowiedź na to pytanie prawdopodobnie przełoży się bezpośrednio na odpowiedź na wcześniejsze pytanie, ale różnica sprawia, że ​​jest to wystarczająco granica, że ​​nie chcę się zamykać jednostronnie.
Peter Taylor,
29
Bardzo miłe pytanie. Jestem absolutnie za pytaniem o ezoteryczne programowanie i niekonwencjonalne modele obliczeniowe , ale przygotuj się na głosowanie niektórych osób, ponieważ obecnie nie pasuje to do zakresu, w jakim ludzie zgadzają się na meta. Chciałbym, aby to stało się precedensem dla takich pytań. :)
Martin Ender
1
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Alex A.,
4
Takie pytania sprawiają, że chciałbym mieć nagrodę za pytanie.
xnor
1
Mam dozwolone eval2453 znaki window.
CalculatorFeline

Odpowiedzi:

23

Po burzy mózgów wydaje się, że przynajmniej w nowoczesnych przeglądarkach nie ma takiej możliwości.

Spróbuję podsumować cały proces, dodając uzasadnienie, dlaczego wyczerpaliśmy nasze opcje w dowolnej domenie przed przejściem dalej. Następnie, z wyjątkiem jakiegoś niesamowitego nowego wglądu (jak na przykład przypadek składni JavaScript, o którym wszyscy zapominają), będzie całkiem jasne, że nie ma sposobu, aby uzyskać pozostałe litery.

Literały

Jedyne bezpośrednie literały można zrobić ze +()[]są zagnieżdżone puste tablice [], [[]], [[[]]], itd. Stamtąd możemy rozpocząć przesyłanie wartości za pomocą +:

  • +[]dostaje zero, co sztuczka Jensa rozwija do dowolnych liczb całkowitych dodatnich przy użyciu ++.

  • []+[]jest "". W rzeczywistości []+xdaje nam xogólnie ciąg znaków .

[]Następnym zastosowaniem jest indeksowanie. Indeksowanie obiektu poza granicami ( [][[]]) daje ci szansę undefined. Rzucenie tego na ciąg i zindeksowanie wyniku daje litery d e f i n u; rzutowanie go na liczbę całkowitą za pomocą pierwszego +pozwala uzyskać NaN, z którego następują litery a N.

Użycie ++lewy do dowolnej wartości niecałkowitej osiągniętej do tej pory daje NaNalbo błąd. Ponadto żaden z obiektów, które możemy stworzyć, nie jest możliwy do wywołania (jeszcze), więc ()nie pomaga (z wyjątkiem grupowania).

Pozostałe sztuczki w naszym rękawie to rzucanie i indeksowanie. Pytanie zatem brzmi: które łańcuchy możemy stworzyć używając znaków, 0123456789adefinuNktóre albo

  • są literałami liczbowymi, które możemy w obie strony rzutować na liczbę całkowitą, aby uzyskać nowe ciągi, lub
  • są nazwy właściwości obiektów, do których możemy już dotrzeć?

Literały liczbowe

Jako przykład drugiej opcji możemy wykonać ciąg znaków "1e1000", a następnie pobrać Infinityz niego +"1e1000", a rzutowanie go z powrotem na ciąg spowoduje, że otrzymamy litery yi I.

Możemy również tworzyć "11e100", rzutować na liczbę i wracać do łańcucha, aby uzyskać "1.1e+101", z którego wyodrębniamy .i +.

Za pomocą tego .z kolei możemy wykonać sznurek ".0000001", rzucić go na numer i z powrotem, aby uzyskać "1e-7", wygrywając nas -.

To w zasadzie wszystkie zmiennoprzecinkowe dostaną: nie ma żadnych ciekawszych wartości innych niż Infinityi NaN, i nie ma więcej znaków używanych w ich zwykłych reprezentacjach łańcuchowych innych niż -+.0123456789e.

Nieruchomości

Więc mamy litery -+.0123456789adefinuyIN. Do jakich nieruchomości możemy dotrzeć? Zapytajmy JavaScript.

>>> R = /^[-+.0123456789adefinuyIN]+$/
>>> [Array, Object, String, Number].reduce((h, f) => {
        h[f.name] = Object.getOwnPropertyNames(f.prototype).filter(x => x.match(R));
        return h }, {})

{ Array: [ 'find' ], Object: [], String: [], Number: [] }

Tylko te [].find, które Jens już znalazł. Rzućmy to na ciąg, zbieraj wszystkie jego litery i spróbuj ponownie. Reprezentacja ciągu jest nieco inna w różnych przeglądarkach. W Chrome i Edge "function find() { [native code] }"zawiera acdefinotuv()[]{}i spację; nasz pełny alfabet jest teraz +-.()[]{}0123456789INacdefinotuvy. W przeglądarce Firefox jest więcej spacji i znaków nowej linii, ale litery są takie same.

Powtarzamy nasze wyszukiwanie:

>>> R = /^[+-.()\[\]{}0123456789INacdefinotuvy]+$/
>>> [Array, Object, String, Number, Function].reduce((h, f) => {
        h[f.name] = Object.getOwnPropertyNames(f.prototype).filter(x => x.match(R));
        return h }, {})

{ Array: [ 'concat', 'find' ],
  Object: [],
  String: [ 'concat' ],
  Number: [],
  Function: [] }

String.prototype.concatjest przestarzałe: robi dokładnie to, co +robi, co możemy już zrobić. Więc mamy Array.prototype.concati Array.prototype.find. Co możemy z nimi zrobić?

Funkcje

concat()pozwala nam stworzyć po raz pierwszy dłuższe tablice. [[]].concat([[]])jest [[], []], a rzucenie tego na sznurek nas dopadnie ",". (To nie pomaga nam znaleźć nowych właściwości.) Ale .concatnie modyfikuje naszych wartości i nigdy nie może wrócić nullani nic takiego.

Dzwonienie find()też nam nie pomaga: dokumentacja MDN mówi

find()Sposób powraca do wartości w tablicy, a element w tablicy spełnia podaną funkcję testowania. W przeciwnym razie undefinedjest zwracany.

Oba te, które możemy już zrobić za pomocą indeksowania.


A stąd nie ma dokąd pójść. Jeśli wątpisz w cokolwiek, co napisałem, daj mi znać w komentarzach.

Lynn
źródło
1
Moje osobiste podejście Pracowałem już z samych tylko w ciągu ostatnich godzin przyniosły wszystkich możliwych nullfunkcji powracających: String.prototype.match, RegExp.exec, i Array.prototype.includes. Znalezienie tych wszystkich niemożliwych do sformułowania, chyba że istnieje dziwny sposób utworzenia wyrażenia regularnego, o którym nie wiem, doszedłem również do wniosku, że nie ma możliwego sposobu, aby to zrobić.
Conor O'Brien
Niezła analiza! To prawdopodobnie poprawna odpowiedź, ale wciąż mam nadzieję na jakąś sztuczkę ... prawdopodobnie fałszywą nadzieję :)
Jens Renders
Gdybyśmy mogli zdobyć litery do złapania i rzucenia, czy moglibyśmy dostać litery błędu? To jest „hwr”.
Rɪᴋᴇʀ
3
Nawet jeśli konstruujemy łańcuchy "catch"i "throw"czego obecnie nie możemy, potrzebowalibyśmy czegoś evalw rodzaju użycia ich jako słów kluczowych, co jest naszym celem przede wszystkim.
Lynn,
Liczby ujemne są możliwe przy użyciu -i rzutowaniu liczb, ale to nie jest bardzo pomocne.
CalculatorFeline
15

Trzy funkcje w odpowiedzi Lynn nie były aż tak bezużyteczne. Ale tryb ścisły w ECMAScript 5 udaremnił mój plan.

W starszych wersjach JavaScript / ECMAScript istnieje dziwactwo. Jeśli metoda zostanie wywołana bez obiektu, windowzakłada się obiekt globalny . Więc możemy to zrobić:

a = {f:function(){return this}};
a.f();                            // Returns a.
g = a.f;
g();                              // Returns window.
window.g();                       // Also returns window.

Dotyczy to nadal nowoczesnych przeglądarek, ale tylko wtedy, gdy funkcja nie jest zdefiniowana w trybie ścisłym. I wszystkie wbudowane funkcje (z natywnym kodem) wydawały się działać w trybie ścisłym. W starszych przeglądarkach, w których nie ma jeszcze trybu ścisłego, działa to również w przypadku wbudowanych funkcji.

Załóżmy, że korzystamy ze starszych przeglądarek. Następnie, jeśli chcemy window, musimy znaleźć wbudowaną funkcję, która zwraca coś zawierającego this. W ramach naszych jedynych wyborów istnieje funkcja Array.prototype.concat, która właśnie to robi. Możemy to przetestować w następujący sposób:

Number.prototype.concat = Array.prototype.concat;
1..concat(2);                     // Returns [1, 2]
concat = Array.prototype.concat;
window.concat(2);                 // Returns [window, 2]
concat(2)                         // TypeError in modern browsers while
                                  //   returning the same thing in older ones.
concat.bind(window)(2)            // A workaround in modern browsers.

Zasadniczo więc nie ma znaczenia, czy obiekt, do którego jest wywoływany, jest tablicą (ale przynajmniej musi to być obiekt). Po prostu otacza ją tablicą, jeśli nie.

Gdybyśmy mieli window, najpierw moglibyśmy uzyskać ciąg [object Window], odlewając go na ciąg. Dzięki nowej postaci bmożemy uzyskać ri sużyć odpowiednio następujących dwóch wierszy oraz każdej postaci, w której nie mieliśmy constructor:

window["atob"]("cuaa")[0]
window["atob"]("cyaa")[0]

Ale innym problemem jest usunięcie odwołania do obiektu [].concat. Zawijanie go w tablicę i wypakowywanie nie działa, ponieważ [].concatjuż oznacza []["concat"]. Jedyny znany mi sposób, który można by zbudować, +[]()to zwrócenie go z funkcji. Array.prototype.findwydawało się, że jest w stanie to zrobić:

[[]["concat"]]["find"](x=>1)      // Returns Array.prototype.concat, where x=>1 can
                                  //   be replaced with any always truthy function.

Zawsze mieliśmy prawdziwe funkcje. Array.prototype.concati String.prototype.concatoba zwracają prawdę, jeśli obiekt jest window. Jeśli skorzystamy z późniejszej, skorzystaliśmy ze wszystkich trzech dostępnych funkcji.

Ale niestety Array.prototype.findnie istnieje w starej przeglądarce, której używamy. Przynajmniej nie znalazłem takiego, który działa. I nie znalazłem innego sposobu na usunięcie odwołania do obiektu.

Pełny kod, który można przetestować w nowoczesnych przeglądarkach, który zwraca ri swraz z .bind(window)obejściem:

[[]["concat"]]["find"](""["concat"].bind(window)).bind(window)()[0]["ato"+([]+[[]["concat"]]["find"](""["concat"].bind(window)).bind(window)()[0])[2]]("cuaa")[0];
[[]["concat"]]["find"](""["concat"].bind(window)).bind(window)()[0]["ato"+([]+[[]["concat"]]["find"](""["concat"].bind(window)).bind(window)()[0])[2]]("cyaa")[0]
jimmy23013
źródło
Fajne informacje. Jakie przeglądarki wypróbowałeś?
Lynn,
@Lynn Niewiele. Głównie Firefox 3.6.0 i 25.0. Czytałem tu i tutaj, że findprzyszedł znacznie później niż tryb ścisły, więc znalezienie czegoś działającego jest mało prawdopodobne. Zapytałem o Edge'a, ponieważ pomyślałem, że może mieć szansę na wolniejszą kompatybilność wsteczną niż przestrzeganie standardu. Próbowałem także Konquerora z tego samego powodu. I niektóre przeglądarki linii poleceń, ale żadna z nich nawet nie obsługuje JavaScript.
jimmy23013
Wypróbowałem Safari 7.1 i 8 oraz niektóre losowe, rzekomo domyślne przeglądarki na telefonach na stronie z zrzutami ekranu przeglądarki. Do tej pory nie działa.
jimmy23013
@ jimmy23013 Wypróbuj Safari 5.0 lub 5.1. Według Czy mogę używać , częściowe wsparcie w starszych Safari odnosi się do trybu ścisłego, który nadal akceptuje wiele JS, które należy uznać za nieprawidłowe. Choć findjeszcze nie został zaimplementowany, może częściowo? ... Gdyby tylko znalazł się na ich liście ...
mbomb007