This question already has an answer here:
这个问题在这里已有答案:
- Determine original name of variable after its passed to a function 5 answers
- 在传递给函数5答案后确定变量的原始名称
What I want to do is get the NAME of a variable passed to a function and the VALUE of that variable and only have to pass in one variable to the function. So:
我想要做的是获取传递给函数的变量的NAME和该变量的VALUE,并且只需要将一个变量传递给函数。所以:
var x = "anything";
function showName() {
}
showName(x);
or
要么
showName("x");
Which will return: "x = anything".
哪个将返回:“x =任何东西”。
Right now, I have to do:
现在,我必须这样做:
showName("x", x);
in order to get the name and value of the variable I am passing in. Note that I am not interested in the name of argument in the prototype of showName, but the name of the variable in the calling function. Also, the variable may be local, so I can't use the window object to find the variable.
为了获取我传入的变量的名称和值。请注意,我对showName原型中的参数名称不感兴趣,但是对调用函数中的变量名称不感兴趣。此外,变量可能是本地的,因此我无法使用window对象来查找变量。
7 个解决方案
#1
55
The short answer is that you can't.
简短的回答是,你做不到。
The longer, evil answer is that you sort of can with some real nastiness. And it only works when called from another function.
更长,更邪恶的答案是你可以带着一些真正的肮脏。它只能在从另一个函数调用时才有效。
there are two interesting attributes available to you that could help
有两个有趣的属性可供您使用
arguments.callee caller
arguments.callee调用者
for fn to do something like this:
为fn做这样的事情:
(function(){
var showMe = function(s){
alert(arguments.callee.caller.toString().match(/showMe\((\S)\)/)[1] +
' = '+ s)
}
x = 1
showMe(x)
})()
What arguments.callee.caller.toString().match(..)[1] does is look for the showMe being called in the function calling it and prints it and its value.
arguments.callee.caller.toString()。match(..)[1]的作用是查找在调用它的函数中调用的showMe并打印它及其值。
But this is still pretty limited because it will only hit the first call of showMe(x). So if there is two calls to it, it won't work.
但这仍然非常有限,因为它只会触及showMe(x)的第一个调用。因此,如果有两个调用它,它将无法工作。
But, it was fun to play with these arcane things.
但是,玩这些神秘的东西很有趣。
#2
8
var x = "anything";
function showName(s) {
alert(s + " = " + eval(s));
}
showName("x");
Not recommended, but there it is.
不推荐,但它确实存在。
#3
4
I already knew that I could pass in a object:
我已经知道我可以传入一个对象:
{a:"this is a"}
where a is name of the variable but I really want to just pass in a variable or the name of a variable (a or "a") and let the function somehow find the name of the variable and its value.
其中a是变量的名称,但我真的只想传入变量或变量的名称(a或“a”),让函数以某种方式找到变量的名称及其值。
The reason I want to do this somewhat weird thing is that I am writing a debug print routine. If I call it like this:
我想做这个有点奇怪的事情的原因是我正在编写调试打印例程。如果我这样称呼它:
var x = "some string";
say(x);
or
要么
say("x");
I want it to print something like:
我想要它打印像:
X (string) = some string
I can pretty reliably find the type of a variable passed, and so I know how to print it, but I really want to try to avoid the redunancy of having to call it like this:
我可以非常可靠地找到传递的变量的类型,所以我知道如何打印它,但我真的想避免不得不像这样调用它的冗余:
say("x", x);
which is what I have to do now.
这就是我现在要做的。
What seems to almost work is OrbMan's answer. Sure, eval is evil, but I think it's OK here because it's only for a debug utility and won't be in the published code. I've made a little test routine of my own using that solution:
看起来几乎可行的是OrbMan的答案。当然,eval是邪恶的,但我认为这里没关系,因为它只适用于调试实用程序,不会出现在已发布的代码中。我使用该解决方案做了一个我自己的小测试程序:
var x = "this is x";
function say(a) {
alert(a + " = " + eval(a));
}
say("x");
and it works but ONLY IF X IS GLOBAL. This doesn't work:
它的工作原理,但只有X是全球的。这不起作用:
function wrapper() {
var x = "this is x";
say("x");
}
So, this solution is close, but since I use almost no Global variables, this isn't going to work. Darn, it is soooo close. What I think I need is "call by name" instead of "by value" or "by reference". And I need a function that will work whether it is being called from another function or not.
所以,这个解决方案很接近,但由于我几乎没有使用全局变量,所以这不会起作用。 Darn,它太近了。我认为我需要的是“按名称呼叫”而不是“按价值”或“按参考”。而且我需要一个无论是否从另一个函数调用它都能工作的函数。
Since I've put in a good many hours on this myself, asking the question here was an act of desperation, I've got to conclude that there really isn't any way to do this. Shucks.
由于我自己花了很多时间,所以在这里提出问题是一种绝望的行为,我必须得出结论,确实没有办法做到这一点。哪里哪里。
To everyone who responded, thanks for all your help.
对于所有回复的人,感谢您的帮助。
#4
2
You could create a hash and pass that in:
您可以创建一个哈希并将其传递给:
var x = {a: 1,b:2}
function showVars(y) {
for (var z in y) { alert(z + " is " + y[z]); }
}
showVars(x);
This doesn't necessarily show the name of the variable, but it does allow for key-value pairs, which may be more to the point of what you need.
这不一定显示变量的名称,但它确实允许键值对,这可能更符合您的需要。
#5
2
This is what I use for debugging. No global variables, no eval, no arguments.callee or arguments.caller:
这是我用于调试的内容。没有全局变量,没有eval,没有arguments.callee或arguments.caller:
var Helpers = (function () {
// ECMAScript 5 strict mode
'use strict';
var Module = {};
Module.debug = function () {
var i;
for (i = 0; i < arguments.length; i++) {
console.log(arguments[i] + ':', this[arguments[i]]);
}
};
Module.SomeObject = function SomeObject() {
this.someMember = 1;
this.anotherMember = 'Whatever';
Module.debug.call(this, 'someMember', 'anotherMember');
var privateMember = {
name: 'Rip Steakface',
battleCry: 'Raaaaaaaaahhhhhhhhhrrrrrrrrrg!'
};
Module.debug.call(privateMember, 'name', 'battleCry');
};
return Module;
}());
For those who are wondering why you would want to do this, it's just a way to efficiently log multiple variables along with their names.
对于那些想知道为什么要这样做的人来说,这只是一种有效记录多个变量及其名称的方法。
If you want to be able to log nested members, as in Module.debug.call(obj, 'hair.fluffiness')
, you can modify the function like so:
如果您希望能够记录嵌套成员,如Module.debug.call(obj,'hair.fluffiness'),您可以像这样修改函数:
Module.debug = function () {
var i, j, props, tmp;
for (i = 0; i < arguments.length; i++) {
tmp = this;
props = arguments[i].split('.');
for (j = 0; j < props.length; j++) {
tmp = tmp[props[j]];
}
console.log(arguments[i] + ':', tmp);
}
};
Unfortunately, I can't find any way to efficiently log multiple private variables that aren't members of an object, e.g. var roll = 3, value = 4; Module.debug.call(???);
不幸的是,我找不到任何方法来有效地记录不是对象成员的多个私有变量,例如var roll = 3,value = 4; Module.debug.call(???);
#6
1
Not sure you can directly get what you want from JavaScript, since the variable name is not carried around with the value it references (think of variable names as identifiers only the compiler knows about; but which get thrown away at runtime).
不确定你可以直接从JavaScript获得你想要的东西,因为变量名不会带有它引用的值(将变量名称视为只有编译器知道的标识符;但是它会在运行时被抛弃)。
You can, however, do something slightly different which allows for passing around named arguments. Create an anonymous object and pass that to your function:
但是,您可以执行稍微不同的操作,以允许传递命名参数。创建一个匿名对象并将其传递给您的函数:
function showNames(o)
{
for( var ix in o )
{
alert( ix + ":" + o[ix] );
}
}
var z = { x : "Anything" }
showNames( z );
// or
showNames( { a : "ay", b : "bee", c: "see" } )
For iterating object properties, I tend to prefer a functional-style, as in:
对于迭代对象属性,我倾向于选择功能样式,如:
Array.iteri = function(o, f)
{
for(var i in o) { f(i, o[i]) }
}
function showNames(o)
{
Array.iteri( o, function(i,v)
{
alert( i + ": " + v )
});
}
showNames( { a : "ay", b : "bee", c: "see" } )
#7
1
The below code is about the best you can do. Unfortunately local variables in a function are properties of the hidden Call Object so they can't be accessed from Javascript like window[a] where a is a property of the window object.
以下代码是关于您可以做的最好的。不幸的是,函数中的局部变量是隐藏调用对象的属性,因此无法从类似window [a]的Javascript访问它们,其中a是window对象的属性。
x = "this is x";
var say = function(a) {
document.write(a + " = " + window[a]);
}
say("x");
var wrapper = function () {
var x = "this is x";
document.write(x + " = " + eval("x"))
}
wrapper()
#1
55
The short answer is that you can't.
简短的回答是,你做不到。
The longer, evil answer is that you sort of can with some real nastiness. And it only works when called from another function.
更长,更邪恶的答案是你可以带着一些真正的肮脏。它只能在从另一个函数调用时才有效。
there are two interesting attributes available to you that could help
有两个有趣的属性可供您使用
arguments.callee caller
arguments.callee调用者
for fn to do something like this:
为fn做这样的事情:
(function(){
var showMe = function(s){
alert(arguments.callee.caller.toString().match(/showMe\((\S)\)/)[1] +
' = '+ s)
}
x = 1
showMe(x)
})()
What arguments.callee.caller.toString().match(..)[1] does is look for the showMe being called in the function calling it and prints it and its value.
arguments.callee.caller.toString()。match(..)[1]的作用是查找在调用它的函数中调用的showMe并打印它及其值。
But this is still pretty limited because it will only hit the first call of showMe(x). So if there is two calls to it, it won't work.
但这仍然非常有限,因为它只会触及showMe(x)的第一个调用。因此,如果有两个调用它,它将无法工作。
But, it was fun to play with these arcane things.
但是,玩这些神秘的东西很有趣。
#2
8
var x = "anything";
function showName(s) {
alert(s + " = " + eval(s));
}
showName("x");
Not recommended, but there it is.
不推荐,但它确实存在。
#3
4
I already knew that I could pass in a object:
我已经知道我可以传入一个对象:
{a:"this is a"}
where a is name of the variable but I really want to just pass in a variable or the name of a variable (a or "a") and let the function somehow find the name of the variable and its value.
其中a是变量的名称,但我真的只想传入变量或变量的名称(a或“a”),让函数以某种方式找到变量的名称及其值。
The reason I want to do this somewhat weird thing is that I am writing a debug print routine. If I call it like this:
我想做这个有点奇怪的事情的原因是我正在编写调试打印例程。如果我这样称呼它:
var x = "some string";
say(x);
or
要么
say("x");
I want it to print something like:
我想要它打印像:
X (string) = some string
I can pretty reliably find the type of a variable passed, and so I know how to print it, but I really want to try to avoid the redunancy of having to call it like this:
我可以非常可靠地找到传递的变量的类型,所以我知道如何打印它,但我真的想避免不得不像这样调用它的冗余:
say("x", x);
which is what I have to do now.
这就是我现在要做的。
What seems to almost work is OrbMan's answer. Sure, eval is evil, but I think it's OK here because it's only for a debug utility and won't be in the published code. I've made a little test routine of my own using that solution:
看起来几乎可行的是OrbMan的答案。当然,eval是邪恶的,但我认为这里没关系,因为它只适用于调试实用程序,不会出现在已发布的代码中。我使用该解决方案做了一个我自己的小测试程序:
var x = "this is x";
function say(a) {
alert(a + " = " + eval(a));
}
say("x");
and it works but ONLY IF X IS GLOBAL. This doesn't work:
它的工作原理,但只有X是全球的。这不起作用:
function wrapper() {
var x = "this is x";
say("x");
}
So, this solution is close, but since I use almost no Global variables, this isn't going to work. Darn, it is soooo close. What I think I need is "call by name" instead of "by value" or "by reference". And I need a function that will work whether it is being called from another function or not.
所以,这个解决方案很接近,但由于我几乎没有使用全局变量,所以这不会起作用。 Darn,它太近了。我认为我需要的是“按名称呼叫”而不是“按价值”或“按参考”。而且我需要一个无论是否从另一个函数调用它都能工作的函数。
Since I've put in a good many hours on this myself, asking the question here was an act of desperation, I've got to conclude that there really isn't any way to do this. Shucks.
由于我自己花了很多时间,所以在这里提出问题是一种绝望的行为,我必须得出结论,确实没有办法做到这一点。哪里哪里。
To everyone who responded, thanks for all your help.
对于所有回复的人,感谢您的帮助。
#4
2
You could create a hash and pass that in:
您可以创建一个哈希并将其传递给:
var x = {a: 1,b:2}
function showVars(y) {
for (var z in y) { alert(z + " is " + y[z]); }
}
showVars(x);
This doesn't necessarily show the name of the variable, but it does allow for key-value pairs, which may be more to the point of what you need.
这不一定显示变量的名称,但它确实允许键值对,这可能更符合您的需要。
#5
2
This is what I use for debugging. No global variables, no eval, no arguments.callee or arguments.caller:
这是我用于调试的内容。没有全局变量,没有eval,没有arguments.callee或arguments.caller:
var Helpers = (function () {
// ECMAScript 5 strict mode
'use strict';
var Module = {};
Module.debug = function () {
var i;
for (i = 0; i < arguments.length; i++) {
console.log(arguments[i] + ':', this[arguments[i]]);
}
};
Module.SomeObject = function SomeObject() {
this.someMember = 1;
this.anotherMember = 'Whatever';
Module.debug.call(this, 'someMember', 'anotherMember');
var privateMember = {
name: 'Rip Steakface',
battleCry: 'Raaaaaaaaahhhhhhhhhrrrrrrrrrg!'
};
Module.debug.call(privateMember, 'name', 'battleCry');
};
return Module;
}());
For those who are wondering why you would want to do this, it's just a way to efficiently log multiple variables along with their names.
对于那些想知道为什么要这样做的人来说,这只是一种有效记录多个变量及其名称的方法。
If you want to be able to log nested members, as in Module.debug.call(obj, 'hair.fluffiness')
, you can modify the function like so:
如果您希望能够记录嵌套成员,如Module.debug.call(obj,'hair.fluffiness'),您可以像这样修改函数:
Module.debug = function () {
var i, j, props, tmp;
for (i = 0; i < arguments.length; i++) {
tmp = this;
props = arguments[i].split('.');
for (j = 0; j < props.length; j++) {
tmp = tmp[props[j]];
}
console.log(arguments[i] + ':', tmp);
}
};
Unfortunately, I can't find any way to efficiently log multiple private variables that aren't members of an object, e.g. var roll = 3, value = 4; Module.debug.call(???);
不幸的是,我找不到任何方法来有效地记录不是对象成员的多个私有变量,例如var roll = 3,value = 4; Module.debug.call(???);
#6
1
Not sure you can directly get what you want from JavaScript, since the variable name is not carried around with the value it references (think of variable names as identifiers only the compiler knows about; but which get thrown away at runtime).
不确定你可以直接从JavaScript获得你想要的东西,因为变量名不会带有它引用的值(将变量名称视为只有编译器知道的标识符;但是它会在运行时被抛弃)。
You can, however, do something slightly different which allows for passing around named arguments. Create an anonymous object and pass that to your function:
但是,您可以执行稍微不同的操作,以允许传递命名参数。创建一个匿名对象并将其传递给您的函数:
function showNames(o)
{
for( var ix in o )
{
alert( ix + ":" + o[ix] );
}
}
var z = { x : "Anything" }
showNames( z );
// or
showNames( { a : "ay", b : "bee", c: "see" } )
For iterating object properties, I tend to prefer a functional-style, as in:
对于迭代对象属性,我倾向于选择功能样式,如:
Array.iteri = function(o, f)
{
for(var i in o) { f(i, o[i]) }
}
function showNames(o)
{
Array.iteri( o, function(i,v)
{
alert( i + ": " + v )
});
}
showNames( { a : "ay", b : "bee", c: "see" } )
#7
1
The below code is about the best you can do. Unfortunately local variables in a function are properties of the hidden Call Object so they can't be accessed from Javascript like window[a] where a is a property of the window object.
以下代码是关于您可以做的最好的。不幸的是,函数中的局部变量是隐藏调用对象的属性,因此无法从类似window [a]的Javascript访问它们,其中a是window对象的属性。
x = "this is x";
var say = function(a) {
document.write(a + " = " + window[a]);
}
say("x");
var wrapper = function () {
var x = "this is x";
document.write(x + " = " + eval("x"))
}
wrapper()