变量名称作为Javascript中的字符串


154

有没有办法在Javascript中将变量名作为字符串获取?(例如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中:如何在PHP 中将变量名作为字符串获取?


2
@delnan实际上,+ 1。除了“如果可以编写variablesName(myFirstName),您已经知道变量名”,我想不出另一种方法了。我正在尝试,但我不能...
降低


1
也许为此,您可以将其存储在变量中,然后将其转换为json例如{“ instanceA”:instanceA}并使用ajax或get / post调用将其发送到服务器,并且可以在php中进行处理并获取实例的名称...
Geomorillo 2014年

@deceze,当然,您知道名称,但这并不意味着您可以/希望手动输入该名称。也许您想转储一堆变量以进行调试,而不希望console.log("myvar = " + myvar);为每个变量一遍又一遍地手动键入。
Synetech

Answers:


54

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

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


125
虽然不回答问题。
htafoya

1
@htafoya:是的,间接地-所有属性objname: value成对打印。但是说明文字可能会更清楚。
马特

1
@Mat我理解代码,但通常OP问题用于动态分配等更复杂的事情,您可以从生成的字符串中选择变量。或者仅创建字典以打印值的方法就太过分了。
htafoya

2
@htafoya-是的,像C#中的nameof(varname)这样简单。
马特

1
我认为这个“不回答问题”的唯一原因是因为它不是以“您无法在JavaScript中获取常量或变量的名称。最接近您想要的...”的名称开头,例如这个其他答案:stackoverflow.com/a/37393679
bigpopakap

86

与Seth的答案类似,但Object.keys()改用:

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

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


5
@titusfx,您可以将const换成let或var,它的工作原理相同。但是,如果您首先使用Transpiler进行对象分解,则它可能已经支持const。
SethWhite '17

这似乎取决于使用ES6吗?
O'Rooney

1
@ O'Rooney是的,它特定于ES6。
甜甜圈

63

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

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

// returns "myFirstName"

3
这个答案类似于[@ SethWhite's](stackoverflow.com/a/39669231/5876282),但大大简化了。谢谢!@bluejayke我认为这个答案要比最初接受的答案晚了几年。但是,是的,目前这是最好的-也许除了“弹出()”的使用建议如下
乙查尔斯^ h

1
是否有可能使函数接受变量并打印其名称?我尝试将您的代码包装在函数中,但id返回我的名字用作参数
Wakan Tanka

@WakanTanka如果您提出适当的问题,我会在那儿回答。
陌生人研究员

@WakanTanka不,那是行不通的。正如您所发现的,它只会打印您给函数自变量指定的名称。我认为这有助于将此类功能编译为较旧的Javascript规范。您可以在此示例(jsfiddle.net/bigpopakap/wq891ghr/2)中看到,{variable}语法只是{variable:variable}的缩写,因此无法使用调用函数中的变量名
bigpopakap

42

在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/


1
好答案!对象销毁的这种特殊用法对我来说是新的(第2行let nameObject = {myVar}非常有用!它似乎在任何地方都没有记录。有任何链接吗?)
Laurence Lord

2
@LaurenceLord它称为属性简写。分配没有定义的对象属性(某事:“ asdf”),将导致JS用变量名称及其值{something} === {something:something}定义该属性。ariya.io/2013/02/...
SethWhite

19
var x = 2;
for(o in window){ 
   if(window[o] === x){
      alert(o);
   }
}

但是,我认为您应该喜欢“ karim79”


8
这仅在窗口范围内起作用(在函数内部时中断)。
jpillora 2015年

1
同意-但最接近回答OP的问题。j
Dembinski

同样,如果您正在测试基本体,它将警告所有具有相同值的变量,或者两个变量具有分配给它们的相同对象。例如,如果第一行是,x = 2; y = 2;或者x = {a:1}; b = x;它会警告每个人
aljgom

如果您希望此功能函数范围内起作用,则可以尝试使用函数名而不是window,例如: var foo = function f(){ f.x = 2; for(o in f){ if(f[o]===f.x) alert(o); } }然后调用f()将发出警报“ x”
aljgom

1
@aljgom-好点。这是一个小提琴来尝试。
马特

16

这适用于基本表达

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);


2
这实际上效果很好!唯一的问题是当您传递这样的内容时:nameof(()=> options.subOptions.displaySize)返回“ subOptions”,而是使用了此正则表达式:exp.toString()。match(/(?? [[^ 。] * $)(\ w +)/ g)[0]
吉姆·布朗

我从以下位置得到未定义:var a = {b:“ c”}; 警报(名称(a)); 函数名称(exp){exp.toString()。match(/(?= [^。] * $)(\ w +)/ g)[0]; } //名字
大卫·斯佩克特

@JimBrown,谢谢!您的评论需要标记为答案!
evorios

14

为了安全起见,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'"

3
如果将myFirstName作为参数v传递给函数(包含此代码),则variableName将报告为v而不是myFirstName。
David Spector

9
var somefancyvariable = "fancy";
Object.keys({somefancyvariable})[0];

由于它返回函数变量的名称,因此无法将其制成函数。

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

编辑:感谢@Madeo指出如何使之成为一个功能此

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

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


错误:“找不到变量键”
Alexander Volkov

密钥未定义
avalanche1

1
应该是这样 const getVarName = (v) => Object.keys(v)[0];,然后调用这样的函数getVarName({whatEverVariable})
Madeo

6

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);


4

当有一个函数编写一个可以更改不同全局变量值的函数时,它并不总是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”。


2
这是不可靠的。窗口对象上可以有任意数量的具有相同值的变量。
泰勒·布坎南

2

您可以反思javascript中的类型并获取属性和方法的名称,但是您需要的东西就像Lambda Expressions Trees.NET中一样,我认为由于javascript的动态性质和缺少静态类型系统,这是不可能的。


3
我认为JS不缺少lambda或功能编程的相关工具。

但是我认为.NET中没有等效于表达式树的结构。
Jahan

2

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

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

这仅在变量名当然已知的情况下有效。

拿着这个:

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"height使用window[]命令将其转换为变量。


2
在第二种情况下,height是window对象的属性,因为在窗口范围内声明了相同名称的变量。当在窗口范围而不是函数/闭包中声明变量时,此方法才有效
xoxox '16

2

到目前为止,我已经找到了将变量名作为字符串获取的简捷方法:

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

const whatsMyName = "Snoop Doggy Dogg";

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



0

正如有人建议的那样,我已经基于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")


-3

不,那里没有。
此外,如果您可以编写variablesName(myFirstName),您已经知道变量名称(“ myFirstName”)。


11
如果代码要缩小,则不一定正确;)
秘密

9
同样,nameof(myVariable)在C#中使用eg (返回字符串“ myVariable”)的目的是在重构或对代码进行其他更改时避免错误。常见的用例是将变量名添加到抛出的错误消息中。我认为字符串大部分文字代码的气味,和犯罪嫌疑人,这就是为什么至少Visual Studio中,它们显示了红/橙色我知道,我知道,这个问题是关于JavaScript的,但我只是解释了为什么我在这里结束。
merrr

var test = 1235125142; console.log(Object.keys({test})。pop())//“测试”
bluejayke

1
@bluejayke称我为无知,但8年后,我仍然看不到有什么比console.log('test')您真正需要它时更好的东西。
deceze
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.