是否有一种方法来获得目前在javascript范围内的所有变量?
当前回答
您可以在[[scopes]]中看到作用域及其变量,甚至可以使用console.dir()查看闭包作用域。
示例1:
counterWithClosure = (function () {
let internalVar = 0
return function () {
return ++internalVar
}
})()
counterWithClosure() // 1
counterWithClosure() // 2
counterWithClosure() // 3
console.dir(counterWithClosure)
它会显示“[[Scopes]] > Closure”,“[[Scopes]] > Global”,甚至“[[Scopes]] > Script”中的变量,如果页面有脚本可达的话。
图片输出:
即使使用嵌套闭包,也可以看到嵌套作用域。
示例2:
adderWithNestedClosures = (function () {
let varLevel1 = 1
return function (param1) {
let varLevel2 = 10
return function (param2) {
let varLevel3 = 100
return function (param3) {
let varLevel4 = 1000
return function (param4) {
++varLevel1
++varLevel2
++varLevel3
++varLevel4
return {
paramsSum: param1 + param2 + param3 + param4,
varsSum: varLevel1 + varLevel2 + varLevel3 + varLevel4
}
}
}
}
}
})()
adderWith123 = adderWithNestedClosures(1)(2)(3) // Preparing function with nested scopes
adderWith123(4) // {paramsSum:10,varsSum:1115}
adderWith123(4) // {paramsSum:10,varsSum:1119}
adderWith123(5) // {paramsSum:11,varsSum:1123}
console.dir(adderWith123)
它显示了[[scopes]]中的所有嵌套作用域 图片输出:
它适用于基于chromium的浏览器。
其他回答
不。“作用域内”变量由“作用域链”决定,不能通过编程方式访问。
有关详细信息(相当多),请查看ECMAScript (JavaScript)规范。这里有一个官方页面的链接,你可以在那里下载规范规范(PDF格式),这里有一个官方的,可链接的HTML版本。
根据您对Camsoft的评论进行更新
The variables in scope for 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 this and 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 (this and arguments; if you're not sure what arguments they give you, you can find out via the arguments variable that's implicitly defined for every function).
所以除了你定义函数的作用域之外,你还可以通过其他方法找到其他可用的函数:
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的开发工具(即使你通常不使用Chrome进行开发)或Firebug(即使你通常不使用Firefox进行开发),或Opera上的Dragonfly,或IE上的“F12开发工具”之类的调试器。并通读它们提供的任何JavaScript文件。然后打他们的头找个合适的医生。: -)
是也不是。几乎在任何情况下都说“不”。“是的”,但如果您想检查全局作用域,则只能以有限的方式进行。举个例子:
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
因此,可以在当前范围内列出一些变量,但它不可靠、不简洁、不高效或不容易访问。
一个更好的问题是,为什么要知道作用域内的变量是什么?
您可以在[[scopes]]中看到作用域及其变量,甚至可以使用console.dir()查看闭包作用域。
示例1:
counterWithClosure = (function () {
let internalVar = 0
return function () {
return ++internalVar
}
})()
counterWithClosure() // 1
counterWithClosure() // 2
counterWithClosure() // 3
console.dir(counterWithClosure)
它会显示“[[Scopes]] > Closure”,“[[Scopes]] > Global”,甚至“[[Scopes]] > Script”中的变量,如果页面有脚本可达的话。
图片输出:
即使使用嵌套闭包,也可以看到嵌套作用域。
示例2:
adderWithNestedClosures = (function () {
let varLevel1 = 1
return function (param1) {
let varLevel2 = 10
return function (param2) {
let varLevel3 = 100
return function (param3) {
let varLevel4 = 1000
return function (param4) {
++varLevel1
++varLevel2
++varLevel3
++varLevel4
return {
paramsSum: param1 + param2 + param3 + param4,
varsSum: varLevel1 + varLevel2 + varLevel3 + varLevel4
}
}
}
}
}
})()
adderWith123 = adderWithNestedClosures(1)(2)(3) // Preparing function with nested scopes
adderWith123(4) // {paramsSum:10,varsSum:1115}
adderWith123(4) // {paramsSum:10,varsSum:1119}
adderWith123(5) // {paramsSum:11,varsSum:1123}
console.dir(adderWith123)
它显示了[[scopes]]中的所有嵌套作用域 图片输出:
它适用于基于chromium的浏览器。
你不能。
变量,函数声明的标识符和函数代码的参数,被绑定为变量对象的属性,这是不可访问的。
参见:
作用域链和标识符解析
在ECMAScript 6中,通过使用代理对象将代码包装在with语句中或多或少是可行的。注意,它需要非严格模式,这是不好的做法。
函数storeVars(目标){ 返回新的代理(目标,{ 有(目标,道具){返回true;}, Get(目标,道具){返回(道具在目标中?目标:窗口)[道具];} }); } Var vars = {};//外部变量,未存储。 (storeVars (var)) { Var a = 1;//存储在vars中 Var b = 2;//存储在vars中 (函数(){ Var c = 3;//内部变量,未存储 }) (); } console.log (var);
代理声称拥有with中引用的所有标识符,因此变量赋值存储在目标中。对于查找,代理从代理目标或全局对象(而不是父作用域)检索值。Let和const变量不包括在内。
灵感来自Bergi的回答。