确定变量传递给函数后的原始名称

Determine original name of variable after its passed to a function

提问人:Andy Groff 提问时间:8/4/2010 更新时间:11/26/2022 访问量:11457

问:

我有一种感觉,这可能是不可能的,但我想确定已传递给 javascript 中函数的变量的原始变量名称。我不知道如何更好地解释它,所以看看这个例子是否有意义。

function getVariableName(unknownVariable){
  return unknownVariable.originalName;
}

getVariableName(foo); //returns string "foo";
getVariableName(bar); //returns string "bar";

这是针对我正在使用的jquery插件,我希望能够显示传递给“调试”函数的变量的名称。

JavaScript的

评论

1赞 Sachin Shanbhag 8/4/2010
我不确定这样做的目的是什么,因为您需要对变量值感兴趣,而不是对变量名称感兴趣。
2赞 Tomalak 8/4/2010
程序运行时没有变量名称。没有“当前”的,也没有“原始”的。
2赞 Andy Groff 8/4/2010
哈哈,我认为这是一个遥远的目标,但仍然值得一试。没有太多的目的,但如果你想要上下文,你可以看到插件的当前版本: andygroff.com/jquery-debugger-debugging-plugin 如果您查看对象示例,我更喜欢标题上写着“clothingCompany Properties”,而不是简单的“对象属性” 它不是很重要,但会很好。
2赞 styfle 1/4/2017
一些相关的功能请求:建议将 nameof() 添加到 TypeScript 编译器。如果这落地了,你可以做.nameof(foo) // returns the string "foo"
0赞 styfle 8/11/2018
我在下面更新了我的答案,这让你真正接近使用 ES6。只需添加大括号即可。

答:

24赞 deceze 8/4/2010 #1

你是对的,这在任何理智的方式下都是不可能的,因为只有值被传递到函数中。

评论

13赞 johny why 1/15/2016
疯狂的方式是什么?
13赞 deceze 1/15/2016
获取回溯,获取函数调用的文件和行号,加载该文件的源代码,查找并解析该行,尝试找出哪个变量是您的参数。由于一行上可能有任意数量的函数调用,并且函数可能在运行时被别名,更不用说任务的复杂性了,我希望这样做的疯狂是不言而喻的。
0赞 Offirmo 9/15/2017
这在某种程度上是可能的,请看我的回答。
0赞 Christian Perry 4/4/2021
在所有变量都具有唯一值的情况下,这是可以证明的。请参阅我的代码答案。
0赞 deceze 4/4/2021
@Perry 您当然可以构造非常具体的情况,在这些情况下,您可以将值反转为变量名称,但这远非可推广的。
1赞 styfle 10/12/2013 #2

全局 w/string 方法

下面是一种可用于保留变量名称和值的技术。

// Set up a global variable called g
var g = {};
// All other variables should be defined as properties of this global object
g.foo = 'hello';
g.bar = 'world';

// Setup function
function doStuff(str) {
  if (str in g) {
    var name = str;
    var value = g[str];
    // Do stuff with the variable name and the variable value here
    // For this example, simply print to console
    console.log(name, value);
  } else {
    console.error('Oh snap! That variable does not exist!');
  }
}

// Call the function
doStuff('foo'); // log: foo hello
doStuff('bar'); // log: bar world
doStuff('fakeVariable'); // error: Oh snap! That variable does not exist!

这有效地创建了一个将变量名称映射到其值的字典。如果不重构每个变量,这可能不适用于现有代码。但是使用这种风格,您可以实现此类问题的解决方案。

ES6 对象方法

在 ES6/ES2015 中,您可以初始化一个具有名称和值的对象,这几乎可以实现您想要做的事情。

function getVariableName(unknownVariable) {
  return Object.keys(unknownVariable)[0];
}

var foo = 'hello';
var output = getVariableName({ foo }); // Note the curly brackets
console.log(output);

这之所以有效,是因为您创建了一个新对象,其键和值与变量 foo 相同,在本例中为 。然后,我们的帮助程序方法将第一个键作为字符串获取。foohello

这要归功于这条推文

评论

0赞 Andy Groff 10/20/2013
谢谢你的回答。这是一个很好的解决方案,尽管它确实不能解决我遇到的问题。我正在编写一个调试插件,该插件将创建一个模态警报,其中包含有关变量的信息,包括其名称。它需要与任何 javascript 一起运行,因此将所有变量存储为对象属性不是一个可行的解决方案。谢谢!
0赞 styfle 10/22/2013
@AndyGroff用变量替换变量可能会解决您的问题。但最终,您必须通过字符串而不是标识符来访问变量。gwindow
1赞 RunninglVlan 6/8/2014 #3

好吧,所有全局变量都是全局对象(这个或窗口)的属性,不是吗? 因此,当我想找出变量的名称时,我做了以下函数:

var getName = function(variable) {
  for (var prop in window) {
    if (variable === window[prop]) {
      return prop;
    }
  }
}
var helloWorld = "Hello World!";
console.log(getName(helloWorld)); // "helloWorld"

有时不起作用,例如,如果在没有新运算符的情况下创建了 2 个字符串并且具有相同的值。

评论

1赞 byxor 6/27/2017
这是否取决于在浏览器中运行?还是我误解了是什么?window
3赞 styfle 6/27/2017
如果两个对象具有相同的值,这将不起作用。 它将返回第一个匹配值的名称。此外,在全局范围内定义变量是一种不好的做法。window.a=1;window.b=1;
-1赞 Jude 12/17/2015 #4

将一组唯一变量转换为一个 JSON 对象,我为此编写了此函数

function makeJSON(){ //Pass the variable names as string parameters [not by reference]
ret={};
for(i=0; i<arguments.length; i++){
    eval("ret."+arguments[i]+"="+arguments[i]);
}
return ret;
}

例:

a=b=c=3;
console.log(makeJSON('a','b','c'));

也许这就是这个查询的原因

评论

7赞 deceze 4/30/2016
ret[x] = x;这里绝对没有理由!eval
11赞 Offirmo 9/15/2017 #5

多亏了 ES6,这在某种程度上成为可能:

function getVariableName(unknownVariableInAHash){
  return Object.keys(unknownVariableInAHash)[0]
}

const foo = 42
const bar = 'baz'
console.log(getVariableName({foo})) //returns string "foo"
console.log(getVariableName({bar})) //returns string "bar"

唯一(小)的问题是你必须将未知变量括在 之间,这没什么大不了的。{}

评论

7赞 Cody G 9/29/2017
{foo}只是......所以你只是把它作为一个对象发送。请参阅:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...{foo:42}New notations in ECMAScript 2015
0赞 Offirmo 9/29/2017
@CodyG。我非常清楚这一点。
13赞 Cody G 9/29/2017
那么你不应该说“多亏了 es6 以某种方式成为可能”,你的答案基本上是---“你可以通过将值作为对象发送,并将键作为变量名来做到这一点”......在 es5 中,使用 Object.keys 的 polyfill 也很容易完成,或者只需将带有变量名称的对象作为另一个属性传递即可。
0赞 gamingexpert13 4/30/2021
我真的很喜欢这个想法,但(大)问题是你不能再像对待普通变量一样对待你的未知变量,所以你将不得不重写你的函数来处理对象。例如,如果你的函数中有这一行,它将不再像之前那样工作 “将你的未知变量包装在 ”之间,所以这似乎是一件大事。unknownVariableInAHash + 1{}
4赞 Helwor 1/1/2019 #6

如您所要调试(显示 var 的名称和 var 的值), 我也一直在寻找它,只想分享我的发现。

它不是通过从 var 中检索 var 的名称,而是相反:从 var 的名称(作为字符串)中检索 var 的值。

可以在没有 eval 的情况下做到这一点,并且使用非常简单的代码,条件是将 var 传递到带有引号的函数中,然后全局声明变量:

foo = 'bar';

debug('foo'); 

function debug(Variable) { 
 var Value = this[Variable]; // in that occurrence, it is equivalent to
 // this['foo'] which is the syntax to call the global variable foo
 console.log(Variable + " is " + Value);  // print "foo is bar"
}
-2赞 voathnak 7/9/2020 #7

我想你可以用

getVariableName({foo});

评论

0赞 gre_gor 10/5/2023
多个现有答案已经推荐了这一点。
0赞 Chris Perry 4/4/2021 #8

使用带有 .filter() 的 2D 参考数组

注意:我现在觉得上面@Offermo的答案是最好的答案。留下我的答案供参考,尽管我大多不建议使用它。

这是我独立想出的,它需要显式声明变量名称,并且仅适用于唯一值。(但如果满足这两个条件,则会起作用。

// Initialize some variables
let var1 = "stick"
let var2 = "goo"
let var3 = "hello"
let var4 = "asdf"


// Create a 2D array of variable names
const varNames = [
    [var1, "var1"],
    [var2, "var2"],
    [var3, "var3"]
]


// Return either name of variable or `undefined` if no match
const getName = v => varNames.filter(name => name[0] === v).length
  ? varNames.filter(name => name[0] === v)[0][1]
  : undefined


// Use `getName` with OP's original function
function getVariableName(unknownVariable){
  return getName(unknownVariable)
}

0赞 Anthony 11/26/2022 #9

这是我对同时记录输入名称及其值的看法:

function logVariableAndName(unknownVariable) {
  const variableName = Object.keys(unknownVariable)[0];
  const value = unknownVariable[variableName];
  console.log(variableName);
  console.log(value);
}

然后你可以像logVariableAndName({ someVariable })