获取变量名。javascript“反射”

IT技术 javascript jquery .net reflection
2021-01-19 12:47:02

有没有办法获取变量,就像你可以在 .Net 中用反射做的那样?
就像在这种情况下:

function(x,y,z)
{
    if (x === 0)
        logger.log('variable ' + x.reflectedName ' has invalid value ' + x)
        // logs: 'variable x has invalid value 0)
    ...
}

我发现了类似的问题,需要函数外部的 var 名称(?!),但找不到这个问题。

(jQuery 是一个选项,虽然我想不出如何用它来完成......)

4个回答

其实你CAN这是一个片段:

function getVarName(v) {
    for (var key in window) {
        if (window[key] === v)
            return key;
    }
}
var testvar = 13142;
function test(t) {
    var varName = getVarName(t);
    // window[varName] -- your variable actualy
    alert(varName);
}
test(testvar); // testvar

另一个问题是,如果您创建了一些包含相同变量的变量。然后将返回第一个 var。

var testvar = 13142;var testvar2 = 13142;var testvar = true;或任何物体都会毁了你的一天。任何未在 windows 全局范围内定义的内容也会毁了你的一天。
2021-04-05 12:47:02

由于您使用.NET作为示例,让我们简要地深入研究一下。C# 中,您可以创建一个带有 的函数Expression

void BadArgument<T>(Expression<Func<T>> argExpr)
{
}

但是为了能够从对该函数的调用中提取变量名称,您必须确保调用始终使用完全正确的语法(即使在编译时无法强制执行此操作):

if(x < 0)
    BadArgument(() => x);

所以它可以做到,但它非常脆弱而且非常缓慢。您基本上是在生成指令以根据 lambda 表达式创建整个表达式树() => x,这样您调用的函数就可以解析该表达式树并尝试找到参数的名称。

这种事情可以在javascript中完成吗?当然!

在 javascript 中,闭包是通过内部函数产生的,所以上面的 lambda 表达式的等价物是:

function(){return x;}

由于 javascript 是一种脚本语言,因此每个函数都相当于它自己作为字符串的定义。换句话说,调用.toString()上述函数将产生:

function(){return x;}

这个 jsfiddle 展示了如何在日志风格的函数中利用它。然后您可以自由地解析生成的函数字符串,这只会比解析 .NET 表达式树稍微麻烦一些。此外,获得实际x比.NET更容易:你刚才打电话的功能

但是,仅仅因为您可以做到,并不意味着您应该这样做这是一个很好的奇才客厅技巧,但当它归结为它时,它不值得:

  • 它很脆弱:如果某些开发人员没有正确使用它并为您提供无法解析的功能怎么办?
  • 它不适用于缩小:想象一下收到一条消息,指出变量a的值不正确,因为您的缩小函数更改了您的变量名称。
  • 它增加了开销:即使是 minifier 也不能缩短function(){return x;}到小于"x".
  • 最后,它很复杂。'纳夫说。
@gdoron:我不知道我是否会使用正则表达式。基本上,您只想获取“return”之后和“}”之前的所有内容,并去除任何空格或分号,并快速祈祷调用代码没有给您带来曲线球。
2021-03-25 12:47:02
警告!请注意minification,当您缩小*.js 文件时,变量名称可能会改变。@gdoron
2021-03-25 12:47:02
优秀的!我不会按照您的建议使用它,但这是一个很好的答案!顺便说一句,你会用什么正则表达式来x摆脱function(){return x;}
2021-03-31 12:47:02
@ImanMahmoudinasab:我已经提到这是不使用这种方法的第二个原因。
2021-04-03 12:47:02

你不能。但是既然你已经知道变量名(因为你必须用它把它连接到字符串的末尾),为什么不直接输入呢?

IE。:

logger.log('variable x has invalid value '+x);
我认为这个例子是为了简单起见。我假设 OP 想要在变量名称事先未知的情况下执行此操作。但是对于“你不能”+1。
2021-03-19 12:47:02
@gdoron,无论如何您都必须在两个地方更改它们。如果有某种反射方法,那么x.variable_name === "x". 所以if (x === 0) echo "x is 0"有两个地方可以改变它,所以也是if (x === 0) echo x.variable_name + " is 0"
2021-03-19 12:47:02
如果你想提前缓存它,var name = x.variable_name你可以做var name = 'x'. 你会做的任何地方x.variable_name,只要把文字"x"代替,它就会以完全相同的方式工作。
2021-03-21 12:47:02
如果有人用他们自己的变量调用函数怎么办: function(a, b, c),x对他们来说毫无意义。
2021-03-24 12:47:02
事先不知道的示例是一个简单的变量 logger function logVar(value) { console.log('Variable ', value.name, 'has value of ', value)},但是是的,答案是它无法完成。请注意,对于函数,您可以这样做。function logFunctionContents(fn){console.log('Function ', fn.name, 'has content', fn.toSource())}
2021-04-06 12:47:02

很容易得到变量名

//This is variable you want to get the name
var prop;

var obj = {prop};
for(var propName in obj){
  alert(propName);
  break;
}

你也可以在这里试试

已编辑

感谢@Brady 的评论

Object.keys({variableName})[0]会给你变量名。

function(x,y)
{
    const key = (obj) => Object.keys(obj)[0];

    if (x === 0)
        logger.log('variable ' + key({x}) + ' has invalid value ' + x)
        // logs: 'variable x has invalid value 0)
    if (y === 0)
        logger.log('variable ' + key({y}) + ' has invalid value ' + y)
        // logs: 'variable y has invalid value 0)
}
我不认为你有这个问题。再次阅读其他答案或问题。谢谢不管
2021-03-16 12:47:02
实际上,我认为这确实回答了问题并且是一种聪明的方法。在这里,您将变量包装在外部对象中,使用变量名称作为属性名称。然后获取对象的第一个属性,即名称。这可以简化为:Object.keys({prop})[0]
2021-04-14 12:47:02