Czy istnieje sposób na uzyskanie wszystkich zmiennych, które są obecnie objęte zakresem javascript?
javascript
Ian
źródło
źródło
for (v in this) alert(v);
. Jednak nie wszystkie globale są policzalne i nie znam żadnego standardowego sposobu na uzyskanie listy niepoliczalnych.this
,arguments
, parametry i wszystkie zmienne zdefiniowane w załączając zakresów.Odpowiedzi:
Nie. Zmienne „w zakresie” są określane przez „łańcuch zasięgu”, który nie jest dostępny programowo.
Aby uzyskać szczegółowe informacje (całkiem sporo), sprawdź specyfikację ECMAScript (JavaScript). Oto link do oficjalnej strony, na której można pobrać specyfikację kanoniczną (PDF), a tutaj do oficjalnej, możliwej do połączenia wersji HTML.
Zaktualizuj na podstawie Twojego komentarza do Camsoft
Zmienne w zakresie funkcji zdarzenia zależą od tego, gdzie definiujesz funkcję zdarzenia, a nie jak ją nazywają. Ale możesz znaleźć przydatne informacje o tym, co jest dostępne dla twojej funkcji
this
i argumenty, robiąc coś zgodnie z tym, co zauważył KennyTM (for (var propName in ____)
), ponieważ powie ci to, co jest dostępne na różnych obiektach dostarczonych ci (this
i argumentach; jeśli jesteś nie jestem pewien, jakie argumenty ci podają, możesz dowiedzieć się przezarguments
zmienną, która jest domyślnie zdefiniowana dla każdej funkcji).Oprócz tego, co jest poza zakresem, ze względu na to, gdzie definiujesz swoją funkcję, możesz dowiedzieć się, co jeszcze jest dostępne innymi sposobami, wykonując:
(Możesz to rozwinąć, aby uzyskać bardziej przydatne informacje).
Zamiast tego jednak prawdopodobnie użyłbym debuggera, takiego jak narzędzia programistyczne Chrome (nawet jeśli normalnie nie używasz Chrome do programowania) lub Firebug (nawet jeśli normalnie nie używasz Firefox do programowania) lub Dragonfly w Operze lub „F12 Developer Tools” w przeglądarce IE. I przeczytaj wszystkie dostarczone przez Ciebie pliki JavaScript. I pobij ich nad głowę, aby uzyskać odpowiednie dokumenty. :-)
źródło
Chociaż wszyscy odpowiadają „ Nie ” i wiem, że „Nie” jest właściwą odpowiedzią, ale jeśli naprawdę potrzebujesz uzyskać lokalne zmienne funkcji, istnieje ograniczony sposób.
Rozważ tę funkcję:
Możesz przekonwertować swoją funkcję na ciąg:
Otrzymasz źródło funkcji jako ciąg
Teraz możesz używać analizatora składni, takiego jak esprima, do analizowania kodu funkcji i znajdowania deklaracji zmiennych lokalnych.
i znajdź obiekty za pomocą:
w wyniku (usunąłem
console.log(x)
poniżej):Przetestowałem to w Chrome, Firefox i Node.
Ale problem tej metody jest to, że po prostu mają zmienne zdefiniowane w samej funkcji. Na przykład dla tego:
masz tylko dostęp do x, a nie y . Ale nadal możesz używać łańcuchów wywołujących (arguments.callee.caller.caller.caller) w pętli, aby znaleźć lokalne zmienne funkcji wywołujących. Jeśli masz wszystkie lokalne nazwy zmiennych, więc masz zmienne zakresu . Dzięki nazwom zmiennych masz dostęp do wartości za pomocą prostej ewaluacji.
źródło
function getCounter(start){ return function(){ start ++; return start; } } var counter = getCounter(1); var startInClosure = eval.call(counter, 'this.start;'); console.log(startInClosure);
Drukuje,undefined
podczas gdy spodziewam się, że powinno być 2.Tak i nie. „Nie” w prawie każdej sytuacji. „Tak”, ale tylko w ograniczony sposób, jeśli chcesz sprawdzić zasięg globalny. Weź następujący przykład:
Które wyniki, spośród ponad 150 innych rzeczy , następujące:
Można więc wymienić niektóre zmienne w bieżącym zakresie, ale nie jest to wiarygodne, zwięzłe, wydajne ani łatwo dostępne.
Lepszym pytaniem jest to, dlaczego chcesz wiedzieć, jakie zmienne są objęte zakresem?
źródło
for ( var i in window ) { if (window.hasOwnProperty(i)) { console.log(i, window[i]); }}
. Spowoduje to co najmniej zmniejszenie odziedziczonych właściwości, a twoje zmienne będą znajdować się tylko wśród około 50 innych właściwości.W ECMAScript 6 jest to mniej więcej możliwe poprzez zawinięcie kodu w
with
instrukcję za pomocą obiektu proxy. Zauważ, że wymaga trybu nie ścisłego i jest to zła praktyka.Serwer proxy twierdzi, że jest właścicielem wszystkich identyfikatorów, do których istnieją odniesienia
with
, więc przypisania zmiennych są przechowywane w celu. W przypadku wyszukiwań serwer proxy pobiera wartość z obiektu docelowego proxy lub obiektu globalnego (nie zakresu nadrzędnego).let
iconst
zmienne nie są uwzględnione.Zainspirowany tą odpowiedź przez Bergi .
źródło
Nie możesz
Zmienne, identyfikatory deklaracji funkcji i argumenty dla kodu funkcji są powiązane jako właściwości obiektu zmiennej , co jest niedostępne.
Zobacz też:
źródło
with
instrukcja może służyć do wstawiania innych obiektów w łańcuchu).Najprostszy sposób na uzyskanie dostępu do Vars w określonym zakresie
Uwaga: Chcesz to zrobić przeciwko niezminimalizowanym js.
Najprostszy sposób na pokazanie wszystkich nieprywatnych zmiennych
Teraz zobaczysz drzewo obiektów, które możesz rozwinąć o wszystkie zadeklarowane obiekty.
źródło
Jak wszyscy zauważyli: nie możesz. Ale możesz utworzyć obiekt i przypisać do niego wszystkie deklarowane zmienne. W ten sposób możesz łatwo sprawdzić swoje zmienne:
źródło
console.log(window);
jsfiddle.net/4x3TxZrobiłem skrzypce, wdrażając (zasadniczo) powyżej pomysłów nakreślonych przez iman. Oto jak to wygląda po najechaniu myszką na drugie ipsum w
return ipsum*ipsum - ...
Zmienne wchodzące w zakres są podświetlone tam, gdzie zostały zadeklarowane (różnymi kolorami dla różnych zakresów). The
lorem
czerwoną ramką jest zaciemnioną zmienną (nie w zakresie, ale należy do zakresu, jeśli nie byłoby tam drugiej lorem dalej w dół drzewa).Korzystam z biblioteki esprima do analizowania JavaScript i estraverse, escodegen, escope (biblioteki narzędziowe na górze esprima). „Ciężkie podnoszenie” jest wykonywane przez te biblioteki (oczywiście najbardziej złożona jest sama esprima).
Jak to działa
tworzy abstrakcyjne drzewo składniowe. Następnie,
generuje złożoną strukturę danych enkapsulującą informacje o wszystkich zakresach w programie. Reszta zbiera informacje zakodowane w tym obiekcie analitycznym (i samym abstrakcyjnym drzewie składni) i tworzy z niego interaktywny schemat kolorowania.
Tak więc poprawna odpowiedź to w rzeczywistości nie „nie”, ale „tak, ale”. „Ale” jest duże: w zasadzie musisz przepisać znaczące części przeglądarki Chrome (i to devtools) w JavaScript. JavaScript jest kompletnym językiem Turinga, więc oczywiście jest to w zasadzie możliwe. Niemożliwe jest zrobienie wszystkiego bez użycia całego kodu źródłowego (jako łańcucha), a następnie zrobienie z nim bardzo skomplikowanych rzeczy.
źródło
Jeśli chcesz tylko ręcznie sprawdzić zmienne, aby pomóc w debugowaniu, po prostu uruchom debugger:
debugger;
Prosto do konsoli przeglądarki.
źródło