【问题标题】:Variable name as a string in Javascript变量名作为 Javascript 中的字符串
【发布时间】:2011-01-05 08:40:03
【问题描述】:

有没有办法在 Javascript 中将变量名作为字符串获取? (如Cocoa 中的NSStringFromSelector

我想这样做:

var myFirstName = 'John';
alert(variablesName(myFirstName) + ":" + myFirstName);

--> myFirstName:John

更新

我正在尝试使用 JavaScript 连接浏览器和另一个程序。我想将实例名称从浏览器发送到另一个程序的回调方法:

FooClass = function(){};
FooClass.someMethod = function(json) {
  // Do something
}

instanceA = new FooClass();
instanceB = new FooClass();
doSomethingInAnotherProcess(instanceB); // result will be substituted by using instanceB.someMethod();

...

来自另一个程序:

evaluateJavascriptInBrowser("(instanceName).someMethod("resultA");");

在 PHP 中: How to get a variable name as a string in PHP?

【问题讨论】:

  • @delnan 确实,+1。除了“如果你能写variablesName(myFirstName),你已经知道变量名了”,我想不出另一种说法。我正在努力,但我不能......
  • 也许您可以将其存储在一个变量中,然后将其转换为 json 例如 {"instanceA": instanceA} 并使用 ajax 或 get/post 调用将其发送到服务器,您可以处理在 php 中并获取实例的名称...
  • @deceze,当然,你知道这个名字,但这并不意味着你可以/想要手动输入它。也许您想转储一堆变量以进行调试,并且不想为每个变量一次又一次地手动输入console.log("myvar = " + myvar);

标签: javascript


【解决方案1】:

喜欢赛斯的回答,但改用Object.keys()

const varToString = varObj => Object.keys(varObj)[0]

const someVar = 42
const displayName = varToString({ someVar })
console.log(displayName)

【讨论】:

  • @titusfx 您可以将 const 换成 let 或 var ,它的工作原理是一样的。但是,如果您首先使用转译器进行对象解构,它可能已经支持 const。
  • 这似乎依赖于使用ES6?
  • @O'Rooney 是的,它是 ES6 特定的。
  • 好主意。有了它,我们可以创建一个能够按值设置多个输出的函数,从终端参数读取:const getArgs = (varObj:any) => { const keys = Object.keys(varObj); process.argv.slice(2).forEach((arg, i) => varObj[keys[i]] = arg); return varObj; }
【解决方案2】:

您可以使用以下解决方案来解决您的问题:

const myFirstName = 'John'
Object.keys({myFirstName})[0]

// returns "myFirstName"

【讨论】:

  • 这个答案与 [@SethWhite's] (stackoverflow.com/a/39669231/5876282) 类似,但简化了很多。谢谢! @bluejayke我认为这个答案是在最初接受的答案之后几年出现的。但是,是的,目前这是最好的——除了建议的“pop()”用法below
  • 是否可以制作接受变量并打印其名称的函数?我尝试将您的代码包装在一个函数中,但 id 返回了我用作参数的名称
  • @WakanTanka 如果你提出一个合适的问题,我会在那里回答。
  • @WakanTanka 不,那行不通。正如您所发现的,它只会打印您为函数参数提供的名称。我认为了解这样的函数如何编译为旧的 Javascript 规范会有所帮助。您可以在此示例 (jsfiddle.net/bigpopakap/wq891ghr/2) 中看到 {variable} 语法只是 {variable: variable} 的缩写,因此无法使用调用函数中的变量名称
  • 注意:例如,如果您在 VS Code 中使用自动重构将 myFirstName 变量重命名为 myLastName,这将不起作用。它会这样做:Object.keys({ myFirstName: myLastName })[0];
【解决方案3】:

通常情况下,您会在希望将名称映射到某个值并能够同时检索两者的情况下使用哈希表。

var obj = { myFirstName: 'John' };
obj.foo = 'Another name';
for(key in obj)
    console.log(key + ': ' + obj[key]);

【讨论】:

  • 虽然没有回答问题。
  • @htafoya:间接地,是的 - obj 的所有属性都打印为 name: value 对。但解释性文字可能会更清楚。
  • @Mat 我理解代码,但通常 OP 问题用于更复杂的动态分配,您可以从生成的字符串中选择变量。或者简单地创建一个字典来打印一个值是多余的。
  • @htafoya - 是的,就像 C# 中的 nameof(varname) 一样简单。
  • 我认为这个“不回答问题”的唯一原因是因为它不是以“你无法在 JavaScript 中获取常量或变量的名称。最接近什么你想要...”,就像其他答案一样:stackoverflow.com/a/37393679
【解决方案4】:

在 ES6 中,你可以这样写:

let myVar = 'something';
let nameObject = {myVar};
let getVarNameFromObject = (nameObject) => {
  for(let varName in nameObject) {
    return varName;
  }
}
let varName = getVarNameFromObject(nameObject);

确实不是最好看的东西,但它可以完成工作。

这利用了 ES6 的对象解构。

更多信息在这里:https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/

【讨论】:

  • 很好的答案!对象破坏的这种特殊用途对我来说是新的(第 2 行 let nameObject = {myVar} 非常有用!它似乎没有在任何地方记录。有任何链接吗?
  • @LaurenceLord 它被称为属性简写。分配一个没有定义的对象属性(东西:'asdf'),将导致 JS 用变量的名称和它的值 {something} === {something:something} 来定义属性。 ariya.io/2013/02/…
  • @LaurenceLord 旁注:它是 "destructuring" 而不是 "destructing" :) ,尽管这尤其不是“对象”解构这只是赛斯提到的“对象文字属性值速记”。对象解构是 JS 中一个非常具体的术语,指的是 ...var {a,b} = {a: "cool", b: "hot"} 等对象的自动解构。
  • MDN 链接到“速记属性名称” - developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 你的意思是! const getVarNameFromObject = (nameObject) => { return Object.keys(nameObject)[0]; };
【解决方案5】:
var x = 2;
for(o in window){ 
   if(window[o] === x){
      alert(o);
   }
}

但是,我认为你应该像“karim79”一样

【讨论】:

  • 这仅适用于窗口范围(在函数内部中断)。
  • 同意 - 但它最接近回答 OP 的问题。 Gj.
  • 如果你正在测试一个原语,它会提醒所有具有相同值的变量,或者如果两个变量有相同的对象分配给它们。例如,如果第一行是x = 2; y = 2;x = {a:1}; b = x;,它会提醒他们每个人
  • 如果您希望它在 函数范围 中工作,您可以尝试使用函数名称而不是窗口,例如:var foo = function f(){ f.x = 2; for(o in f){ if(f[o]===f.x) alert(o); } } 然后调用 f() 将警告 'x '
  • @aljgom - 好点。这是一个fiddle 来尝试一下。
【解决方案6】:

为了安全起见,pop 可能比使用 [0] 索引更好(变量可能为 null)。

const myFirstName = 'John'
const variableName = Object.keys({myFirstName}).pop();
console.log(`Variable ${variableName} with value '${variable}'`);

// returns "Variable myFirstName with value 'John'"

【讨论】:

  • 如果 myFirstName 作为参数 v 传递给函数(包含此代码),则 variableName 报告为 v 而不是 myFirstName。
【解决方案7】:

这适用于基本表达式

const nameof = exp => exp.toString().match(/[.](\w+)/)[1];

例子

nameof(() => options.displaySize);

片段:

var nameof = function (exp) { return exp.toString().match(/[.](\w+)/)[1]; };
var myFirstName = 'Chuck';
var varname = nameof(function () { return window.myFirstName; });
console.log(varname);

【讨论】:

  • 这实际上效果很好!唯一的问题是当您传入这样的内容时: nameof(() => options.subOptions.displaySize) 返回“subOptions” 相反,我使用了这个正则表达式: exp.toString().match(/(?=[^ .]*$)(\w+)/g)[0]
  • 我未定义来自:var a={b:"c"};警报(名称(a));函数名(exp) { exp.toString().match(/(?=[^.]*$)(\w+)/g)[0]; } // 名称
  • @JimBrown,谢谢!您的评论需要标记为答案!
【解决方案8】:

从任何有效的 Javascript(变量、类)中获取字符串:

const nameOf = (f) => (f).toString().replace(/[ |\(\)=>]/g,'');

例子:

nameOf(() => myVariable)             // myVariable
nameOf(() => myVariable.name)        // myVariable.name
nameOf(() => myVariable.name.length) // myVariable.name.length
nameOf(() => myVariable.name[10])    // myVariable.name[10]
nameOf(() => MySuperClass)           // MySuperClass

【讨论】:

  • 这是对我有用的众多答案中唯一的答案,因为我的“对象”正在复制 C# 枚举,例如:`var myEnum = {A:1, B:5, C: 27}
  • 您能否更新您的答案并创建一个function。我不知道如何使用你的代码。
  • @Radek const nameOf = function (f) { return (f).toString().replace(/[ |\(\)=>]/g,''); }; developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • 这真是天才!
  • 我推荐使用const nameOf = (f) => (f).toString().replace(/(\(\) => )/g,'');。然后就很容易修改了,比如想把“this.var”改成“var”,const nameOf = (f) => (f).toString().replace(/(\(\) => this\.)/g,'');
【解决方案9】:
var somefancyvariable = "fancy";
Object.keys({somefancyvariable})[0];

这不能做成函数,因为它返回函数变量的名称。

// THIS DOESN'T WORK
function getVarName(v) {
    return Object.keys({v})[0];
}
// Returns "v"

编辑:感谢@Madeo pointing out how to make this into a function

function debugVar(varObj) {
    var varName = Object.keys(varObj)[0];
    console.log("Var \"" + varName + "\" has a value of \"" + varObj[varName] + "\"");
}

您需要使用包含变量的单个元素数组调用该函数。 debugVar({somefancyvariable});
编辑:Object.keys 在我测试过的每个浏览器中都可以引用为keys,但根据 cmets,它并非在任何地方都有效。

【讨论】:

  • 错误:“找不到变量键”
  • 键未定义
  • 应该是这样的const getVarName = (v) => Object.keys(v)[0];然后像这样调用函数getVarName({whatEverVariable})
【解决方案10】:

到目前为止我发现的将变量名称作为字符串获取的最短方法:

const name = obj => Object.keys(obj)[0];

const whatsMyName = "Snoop Doggy Dogg";

console.log( "Variable name is: " + name({ whatsMyName }) );
//result: Variable name is: whatsMyName

【讨论】:

    【解决方案11】:

    ECMAScript 5.1 开始,您可以使用 Object.keys 从对象中获取所有属性的名称。

    这是一个例子:

    // Get John’s properties (firstName, lastName)
    var john = {firstName: 'John', lastName: 'Doe'};
    var properties = Object.keys(john);
    
    // Show John’s properties
    var message = 'John’s properties are: ' + properties.join(', ');
    document.write(message);

    【讨论】:

      【解决方案12】:

      使用 Object.keys() 的最佳方式;

      示例:用于在全局范围内获取多个变量名称

      // multi variables for testing
      var x = 5 , b = true , m = 6 , v = "str";
      
      // pass all variables you want in object
      function getVarsNames(v = {}){
          // getting keys or names !
          let names = Object.keys(v);
          // return array contain all names of variables 
          return names;
      }
      
      // testing if that work or not 
      let VarsNames = getVarsNames({x , b , m , v});
      
      console.log(VarsNames); // output is array [x , b , m , v]
      

      【讨论】:

        【解决方案13】:

        您可以反映javascript 中的类型并获取属性和方法的名称,但是您需要的是.NET 中的Lambda Expressions Trees 之类的东西,我认为这是不可能的,因为动态javascript 的性质和缺乏静态类型系统。

        【讨论】:

        • 我不认为 JS 缺少 lambda 或函数式编程的相关工具。
        • 但我认为 .NET 中没有与表达式树等效的结构。
        【解决方案14】:

        我需要这个,不想使用对象,并想出了以下解决方案,扭转了这个问题。

        我没有将变量名转换为字符串,而是将字符串转换为变量。

        这只有在变量名当然知道的情况下才有效。

        拿着这个:

        var height = 120;
        testAlert(height);
        

        这应该显示:

        height: 120
        

        这可以这样完成:

        function testAlert(ta)
        {
            a = window[ta];
            alert(ta + ': ' + a); 
        }
        
        var height = 120;
        testAlert("height");
        // displays: height: 120
        

        所以我使用字符串"height" 并使用window[] 命令将其转换为变量height

        【讨论】:

        • 在第二种情况下,高度是window 对象的属性,因为同名变量是在窗口范围内声明的。这仅在变量在窗口范围内声明时才有效,而不是在函数/闭包中。
        【解决方案15】:

        当让一个函数编写一个改变不同全局变量值的函数时,它并不总是 myfirstname 它是任何碰巧经过的东西。试试这个对我有用。

        jsfiddle运行

        var jack = 'jill';
        function window_getVarName(what)
        {
          for (var name in window)
          {
            if (window[name]==what)
            return(name);
          }
          return("");
        }
        document.write(window_getVarName(jack));
        

        将写入窗口“jack”。

        【讨论】:

        • 这不可靠。窗口对象上可以有任意数量的具有相同值的变量。
        【解决方案16】:

        这在使用 Internet Explorer(9、10 和 11)、Google Chrome 5 时有效:

           
        var myFirstName = "Danilo";
        var varName = Object.keys({myFirstName:0})[0];
        console.log(varName);

        浏览器兼容性表:
        https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

        【讨论】:

        • 谷歌浏览器 5?真的吗??
        • @avalanche1,根据 MDN 版本兼容性表。
        【解决方案17】:

        如果您正在寻找快速而肮脏的东西,这可能会起作用:

        var zox = 150;
        
        cl("zox");
        
        function cl(c) {
            console.log(c + ': ' + this[c]); // zox: 150    
        }
        

        【讨论】:

          【解决方案18】:

          对于那些想要打印 variableName 和 variableValue 以进行调试的人来说,这里有一个函数:

          const printNameValue = (v)=> {
            var varName = (v).toString().replace(/[ |\(\)=>]/g, '')
            var varValue = (v)()
            // neat : console.log(varName,varValue);
            // with some coloring  : 
            console.log("\033[1;96m[\033[1;33m " + varName + " :\033[0;0m " + varValue+"\033[1;96m ]\033[0;0m");
          }
          

          例子:

          const myNiceVariable = 1234
          致电:
          printNameValue(()=> myNiceVariable )
          结果:

          【讨论】:

            【解决方案19】:

            我已经按照某人的建议基于 JSON 创建了这个函数,可以很好地满足我的调试需求

            function debugVar(varNames){
            let strX = "";
            function replacer(key, value){
                if (value === undefined){return "undef"}
                return value
                }    
            for (let arg of arguments){
            let lastChar;
                if (typeof arg!== "string"){
                    let _arg = JSON.stringify(arg, replacer);
                    _arg = _arg.replace('{',"");
                    _arg = _arg.replace('}',"");            
                    _arg = _arg.replace(/:/g,"=");
                    _arg = _arg.replace(/"/g,"");
                    strX+=_arg;
                }else{
                strX+=arg;
                lastChar = arg[arg.length-1];
                }
                if (arg!==arguments[arguments.length-1]&&lastChar!==":"){strX+=" "};
            }
            console.log(strX)    
            }
            let a = 42, b = 3, c;
            debugVar("Begin:",{a,b,c},"end")

            【讨论】:

              【解决方案20】:

              不,没有。
              另外,如果你能写variablesName(myFirstName),你就已经知道变量名(“myFirstName”)了。

              【讨论】:

              • 如果代码被缩小,则不一定正确;)
              • 也是使用例如C# 中的nameof(myVariable)(返回字符串“myVariable”是为了在重构或对代码进行其他更改时屏蔽错误。一个常见的用例是将变量的名称添加到抛出的错误消息中。在大多数情况下,我将字符串文字视为代码气味,并怀疑这就是为什么至少 Visual Studio 以红色/橙色显示它们的原因。我知道我知道,这个问题是关于 Javascript 的,但我只是解释了为什么我在这里结束。
              • var test = 1235125142; console.log(Object.keys({test}).pop()) // “测试”
              • @bluejayke 称我为无知,但 8 年后我仍然看不出它比 console.log('test') 好多少,或者当你真正需要它时。
              猜你喜欢
              • 2013-06-26
              • 1970-01-01
              • 1970-01-01
              • 2020-11-01
              • 2013-08-27
              相关资源
              最近更新 更多