Javascript 获取范围内的所有变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2051678/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting All Variables In Scope
提问by Ian
Is there a way to get all variables that are currently in scope in javascript?
有没有办法获取当前在 javascript 范围内的所有变量?
采纳答案by T.J. Crowder
No. "In scope" variables are determined by the "scope chain", which is not accessible programmatically.
不可以。“作用域内”变量由“作用域链”确定,不能以编程方式访问。
For detail (quite a lot of it), check out the ECMAScript (JavaScript) specification. Here's a linkto the official page where you can download the canonical spec (a PDF), and here's oneto the official, linkable HTML version.
有关详细信息(很多),请查看 ECMAScript (JavaScript) 规范。这是官方页面的链接,您可以在其中下载规范规范(PDF),这是官方可链接的 HTML 版本的链接。
Update based on your comment to Camsoft
根据您对 Camsoft 的评论进行更新
The variables in scopefor your event function are determined by where you define your event function, not how they call it. But, you may find useful information about what's available to your function via thisand arguments by doing something along the lines of what KennyTM pointed out (for (var propName in ____)) since that will tell you what's available on various objects provided to you (thisand arguments; if you're not sure what arguments they give you, you can find out via the argumentsvariable that's implicitly defined for every function).
事件函数作用域内的变量取决于您定义事件函数的位置,而不是它们如何调用它。但是,通过this按照 KennyTM 指出的内容 ( for (var propName in ____))做一些事情,您可能会找到有关通过和参数对您的函数可用的内容的有用信息,因为这将告诉您提供给您的各种对象上的可用内容(this和参数;如果您是不确定他们给你什么参数,你可以通过arguments为每个函数隐式定义的变量找到)。
So in addition to whatever's in-scope because of where you define your function, you can find out what else is available by other means by doing:
因此,除了由于您定义函数的位置而在范围内的任何内容之外,您还可以通过以下方式找出其他可用的内容:
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]);
}
}
(You can expand on that to get more useful information.)
(您可以扩展它以获得更多有用的信息。)
Instead of that, though, I'd probably use a debugger like Chrome's dev tools (even if you don't normally use Chrome for development) or Firebug(even if you don't normally use Firefox for development), or Dragonfly on Opera, or "F12 Developer Tools" on IE. And read through whatever JavaScript files they provide you. And beat them over the head for proper docs. :-)
不过,我可能会使用 Chrome 的开发工具(即使您通常不使用 Chrome 进行开发)或Firebug(即使您通常不使用 Firefox 进行开发)或 Opera 上的 Dragonfly 之类的调试器,或 IE 上的“F12 开发人员工具”。并通读他们为您提供的任何 JavaScript 文件。并击败他们以获得适当的文档。:-)
回答by iman
Although everyone answer "No" and I know that "No" is the right answer but if you really need to get local variablesof a function there is a restricted way.
虽然每个人都回答“否”并且我知道“否”是正确的答案,但是如果您确实需要获取函数的局部变量,则有一种受限的方法。
Consider this function:
考虑这个函数:
var f = function() {
var x = 0;
console.log(x);
};
You can convert your function to a string:
您可以将函数转换为字符串:
var s = f + '';
You will get source of function as a string
您将获得作为字符串的函数源
'function () {\nvar x = 0;\nconsole.log(x);\n}'
Now you can use a parser like esprimato parse function code and find local variable declarations.
现在您可以使用像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);
and find objects with:
并找到对象:
obj.type == "VariableDeclaration"
in the result (I have removed console.log(x)below):
结果(我在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"
}
]
}
I have tested this in Chrome, Firefox and Node.
我已经在 Chrome、Firefox 和 Node.js 中对此进行了测试。
But the problemwith this method is that you just have the variables defined in the function itself. For example for this one:
但是这种方法的问题在于你只是在函数本身中定义了变量。例如对于这个:
var g = function() {
var y = 0;
var f = function() {
var x = 0;
console.log(x);
};
}
you just have access to the xand not y. But still you can use chains of caller(arguments.callee.caller.caller.caller) in a loop to find local variables of caller functions. If you have all local variable names so you have scope variables. With the variable names you have access to values with a simple eval.
您只能访问x而不是y。但是您仍然可以在循环中使用调用者链(arguments.callee.caller.caller.caller)来查找调用者函数的局部变量。如果您拥有所有局部变量名称,那么您就有了作用域变量。使用变量名称,您可以使用简单的 eval 访问值。
回答by Justin Johnson
Yes and no. "No" in almost every situation. "Yes," but only in a limited manner, if you want to check the global scope. Take the following example:
是和否。几乎在所有情况下都是“不”。“是”,但仅限于有限的方式,如果您想检查全局范围。以下面的例子为例:
var a = 1, b = 2, c = 3;
for ( var i in window ) {
console.log(i, typeof window[i], window[i]);
}
Which outputs, amongst 150+ other things, the following:
在 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 '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);
'"
"Firebug command line does not support ''"
_FirebugCommandLine object Object
hasDuplicate boolean false
So it is possible to list some variables in the current scope, but it is not reliable, succinct, efficient, or easily accessible.
所以可以列出当前作用域内的一些变量,但并不可靠、简洁、高效或易于访问。
A better question is why do you want to know what variables are in scope?
一个更好的问题是为什么你想知道哪些变量在范围内?
回答by Oriol
In ECMAScript 6 it's more or less possible by wrapping the code inside a withstatement with a proxy object. Note it requires non-strict mode and it's bad practice.
在 ECMAScript 6 中,通过with使用代理对象将代码包装在语句中或多或少是可能的。请注意,它需要非严格模式,这是不好的做法。
var v = {}; //put everything here
var f = function(a, b){//do something
}; v.f = f; //make's easy to debug
var a = [1,2,3];
v.a = a;
var x = 'x';
v.x = x; //so on...
console.log(v); //it's all there
The proxy claims to own all identifiers referenced inside with, so variable assignments are stored in the target. For lookups, the proxy retrieves the value from the proxy target or the global object (not the parent scope). letand constvariables are not included.
代理声称拥有内部引用的所有标识符with,因此变量分配存储在目标中。对于查找,代理从代理目标或全局对象(而不是父作用域)中检索值。let和const变量不包括在内。
Inspired by this answerby Bergi.
回答by CMS
You can't.
你不能。
Variables, identifiers of function declarations and arguments for function code, are bound as properties of the Variable Object, which is not accesible.
变量,函数声明的标识符和函数代码的参数,被绑定为Variable Object 的属性,这是不可访问的。
See also:
也可以看看:
回答by rafaelcastrocouto
As everyone noticed: you can't. But you can create a obj and assign every var you declare to that obj. That way you can easily check out your vars:
正如每个人都注意到的那样:你不能。但是您可以创建一个 obj 并将您声明的每个 var 分配给该 obj。这样你就可以轻松地查看你的变量:
ast = esprima.parse(sourceString, {range: true, sourceType: 'script'});
回答by Timothy Perez
The Simplest Way to Get Access to Vars in a Particular Scope
在特定范围内访问变量的最简单方法
- Open Developer Tools > Resources (in Chrome)
- Open file with a function that has access to that scope (tip cmd/ctrl+p to find file)
- Set breakpoint inside that function and run your code
- When it stops at your breakpoint, you can access the scope var through console (or scope var window)
- 打开开发者工具 > 资源(在 Chrome 中)
- 使用有权访问该范围的函数打开文件(提示 cmd/ctrl+p 以查找文件)
- 在该函数内设置断点并运行您的代码
- 当它在您的断点处停止时,您可以通过控制台(或范围变量窗口)访问范围变量
Note:You want to do this against un-minified js.
注意:您想针对未缩小的 js 执行此操作。
The Simplest Way to Show All Non-Private Vars
显示所有非私有变量的最简单方法
- Open Console (in Chrome)
- Type: this.window
- Hit Enter
- 打开控制台(在 Chrome 中)
- 类型:this.window
- 按回车键
Now you will see an object tree you can expand with all declared objects.
现在您将看到一个对象树,您可以使用所有声明的对象展开。
回答by mathheadinclouds
I made a fiddleimplementing (essentially) above ideas outlined by iman. Here is how it looks when you mouse over the second ipsum in return ipsum*ipsum - ...
我做了一个小提琴实现(基本上)上述 iman 概述的想法。这是当您将鼠标悬停在第二个 ipsum 上时的外观return ipsum*ipsum - ...
The variables which are in scope are highlighted where they are declared (with different colors for different scopes). The loremwith red border is a shadowed variable (not in scope, but be in scope if the other lorem further down the tree wouldn't be there.)
范围内的变量在声明它们的地方突出显示(不同的范围用不同的颜色)。在lorem与红色边框是一个阴影变量(不在范围内,但在范围上,如果其他LOREM进一步下跌的树不会在那里。)
I'm using esprima library to parse the JavaScript, and estraverse, escodegen, escope (utility libraries on top of esprima.) The 'heavy lifting' is done all by those libraries (the most complex being esprima itself, of course.)
我正在使用 esprima 库来解析 JavaScript,以及 estraverse、escodegen、escope(esprima 之上的实用程序库。)“繁重的工作”全部由这些库完成(当然,最复杂的是 esprima 本身。)
How it works
这个怎么运作
analysis = escope.analyze(ast);
makes the abstract syntax tree. Then,
制作抽象语法树。然后,
##代码##generates a complex data structure encapsulating information about all the scopes in the program. The rest is gathering together the information encoded in that analysis object (and the abstract syntax tree itself), and making an interactive coloring scheme out of it.
生成一个复杂的数据结构,封装有关程序中所有范围的信息。其余的工作是将在该分析对象(以及抽象语法树本身)中编码的信息收集在一起,并从中制定出交互式着色方案。
So the correct answer is actually not "no", but "yes, but". The "but" being a big one: you basically have to rewrite significant parts of the chrome browser (and it's devtools) in JavaScript. JavaScript is a Turing complete language, so of course that is possible, in principle. What is impossible is doing the whole thing without using the entirety of your source code (as a string) and then doing highly complex stuff with that.
所以正确的答案实际上不是“不”,而是“是的,但是”。“但是”很重要:您基本上必须用 JavaScript 重写 chrome 浏览器(及其开发工具)的重要部分。JavaScript 是一种图灵完备的语言,所以原则上当然是可能的。不可能的是在不使用整个源代码(作为字符串)的情况下完成整个事情,然后用它做非常复杂的事情。
回答by David Meister
If you just want to inspect the variables manually to help debug, just fire up the debugger:
如果您只想手动检查变量以帮助调试,只需启动调试器:
debugger;
debugger;
Straight into the browser console.
直接进入浏览器控制台。


