Получение всех переменных в области

Есть ли способ получить все переменные, которые в настоящее время находятся в области видимости в javascript?

Ответ 1

Нет. "В области видимости" переменные определяются "цепочкой видимости", которая недоступна программно.

Для деталей (довольно много), ознакомьтесь с спецификацией ECMAScript (JavaScript). Здесь ссылка на официальную страницу, где вы можете скачать каноническую спецификацию (PDF) и здесь один до официальной, сместимой HTML-версии.

Обновление, основанное на вашем комментарии к Camsoft

Переменные в области для вашей функции события определяются тем, где вы определяете свою функцию события, а не как они ее называют. Но вы можете найти полезную информацию о том, что доступно вашей функции, через this и аргументы, делая что-то в соответствии с тем, что указал KennyTM (for (var propName in ____)), поскольку это скажет вам, что доступно на различные объекты, предоставленные вам (this и аргументы, если вы не знаете, какие аргументы вам дают, вы можете узнать через переменную arguments, которая неявно определена для каждой функции).

Таким образом, помимо того, что вы используете в своей области, вы можете узнать, что еще доступно другими способами:

var n, arg, name;
alert("typeof this = " + typeof this);
for (name in this) {
    alert("this[" + name + "]=" + this[name]);
}
for (n = 0; n < arguments.length; ++n) {
    arg = arguments[n];
    alert("typeof arguments[" + n + "] = " + typeof arg);
    for (name in arg) {
        alert("arguments[" + n + "][" + name + "]=" + arg[name]);
    }
}

(Вы можете расширить его, чтобы получить более полезную информацию.)

Вместо этого я, вероятно, использовал бы отладчик, например, инструменты Chrome dev (даже если вы обычно не используете Chrome для разработки) или Firebug (даже если вы обычно не используете Firefox для разработки), или Dragonfly на Opera, или "Инструменты разработчика F12" в IE. И прочитайте все файлы JavaScript, которые они вам предоставляют. И бить их по голове для правильных документов.: -)

Ответ 2

Хотя все отвечают " Нет", и я знаю, что "Нет" - правильный ответ, но если вам действительно нужно получить локальные переменные для функции, существует ограниченная путь.

Рассмотрим эту функцию:

var f = function() {
    var x = 0;
    console.log(x);
};

Вы можете преобразовать свою функцию в строку:

var s = f + '';

Вы получите источник функции в виде строки

'function () {\nvar x = 0;\nconsole.log(x);\n}'

Теперь вы можете использовать парсер, например esprima, для анализа кода функции и поиска локальных переменных.

var s = 'function () {\nvar x = 0;\nconsole.log(x);\n}';
s = s.slice(12); // to remove "function () "
var esprima = require('esprima');
var result = esprima.parse(s);

и найдите объекты с помощью:

obj.type == "VariableDeclaration"

в результате (я удалил console.log(x) ниже):

{
    "type": "Program",
    "body": [
        {
            "type": "VariableDeclaration",
            "declarations": [
                {
                    "type": "VariableDeclarator",
                    "id": {
                        "type": "Identifier",
                        "name": "x"
                    },
                    "init": {
                        "type": "Literal",
                        "value": 0,
                        "raw": "0"
                    }
                }
            ],
            "kind": "var"
        }
    ]
}

Я тестировал это в Chrome, Firefox и Node.

Но проблема с этим методом заключается в том, что у вас есть только переменные, определенные в самой функции. Например, для этого:

var g = function() {
    var y = 0;
    var f = function() {
        var x = 0;
        console.log(x);
    };
}

у вас просто есть доступ к x, а не y. Но все же вы можете использовать цепочки caller (arguments.callee.caller.caller.caller) в цикле для поиска локальных переменных функций вызывающего абонента. Если у вас есть все имена локальных переменных, у вас есть переменные области видимости. С именами переменных вы получаете доступ к значениям с помощью простого eval.

Ответ 3

Да и нет. "Нет" почти во всех ситуациях. "Да", но только ограниченным образом, если вы хотите проверить глобальный охват. Возьмем следующий пример:

var a = 1, b = 2, c = 3;

for ( var i in window ) {
    console.log(i, typeof window[i], window[i]);
}

Какие выходы, среди 150+ других вещей, следующие:

getInterface function getInterface()
i string i // <- there it is!
c number 3
b number 2
a number 1 // <- and another
_firebug object Object firebug=1.4.5 element=div#_firebugConsole
"Firebug command line does not support '$0'"
"Firebug command line does not support '$1'"
_FirebugCommandLine object Object
hasDuplicate boolean false

Таким образом, можно указать некоторые переменные в текущей области, но не является надежным, кратким, эффективным или легкодоступным.

Лучший вопрос: почему вы хотите знать, какие переменные находятся в области видимости?

Ответ 5

В ECMAScript 6 это более или менее возможно, обернув код внутри оператора with прокси-объектом. Обратите внимание, что это требует нестрогого режима и плохой практики.

function storeVars(target) {
  return new Proxy(target, {
    has(target, prop) { return true; },
    get(target, prop) { return (prop in target ? target : window)[prop]; }
  });
}
var vars = {}; // Outer variable, not stored.
with(storeVars(vars)) {
  var a = 1;   // Stored in vars
  var b = 2;   // Stored in vars
  (function() {
    var c = 3; // Inner variable, not stored.
  })();
}
console.log(vars);

Ответ 6

Как все заметили: вы не можете. Но вы можете создать obj и назначить каждый var, который вы объявляете для obj. Таким образом, вы можете легко проверить свои вары:

var v = {}; //put everything here

var f = function(a, b){//do something
}; v.f = f; //make easy to debug
var a = [1,2,3];
v.a = a;
var x = 'x';
v.x = x;  //so on...

console.log(v); //it all there

Ответ 7

Самый простой способ получить доступ к Vars в особой области

  • Откройте Инструменты разработчикa > Ресурсы (в Chrome)
  • Откройте файл с функцией, имеющей доступ к этой области (подсказка cmd/ctrl + p для поиска файла)
  • Установите точку останова внутри этой функции и запустите свой код
  • Когда он останавливается в точке останова, вы можете получить доступ к области var через консоль (или окно var var)

Примечание: Вы хотите сделать это против un-minified js.

Самый простой способ показать все неживые войны

  • Открыть консоль (в Chrome)
  • Тип: this.window
  • Нажмите Enter

Теперь вы увидите дерево объектов, которое вы можете развернуть со всеми объявленными объектами.

Ответ 8

Если вы просто хотите вручную проверить переменные, чтобы помочь отлаживать, просто запустите отладчик:

debugger;

Прямо в консоль браузера.

Ответ 9

  • получить список каждого слова, которое когда-либо было написано или напечатано любым способом или способом любым человеком с самого начала (определенно конечный список в математическом смысле.)

  • поместите их все в один большой массив, набрав их снова в свою консоль dev (в виде строк, чтобы вы не получили здесь ошибки).

  • создать новый массив и выполнить цикл над конечным списком, нажав на новый массив, если try/catch (выполняющий только это в попытке) не заканчивается catch, из-за ReferenceError (используя eval на "нестрочный", потому что вы хотите здесь ошибку, если не в области).

  • Я беру это обратно. Список, о котором я говорил в пункте 1, недостаточно велик. Они могли бы создать переменные через окно [randomlyGeneratedString] = что-то. Улучшите цикл над всеми строками, которые могут быть сгенерированы любой компьютерной программой, останавливающейся в разумные допустимые временные рамки - скажем, время, прошедшее с момента изобретения компаньона.


Хорошо, серьезно, вы могли бы сделать это так, используя в качестве списка в 1) то, что вы получаете от запуска esprima.parse на всей вашей кодовой базе, и ходите по дереву для вещей под названием "Идентификатор" и сохраняете свое "имя". Но тогда вы пропустите переменные, созданные как в окне [ "file_" + i] = blah, см. 4.