Имя переменной в виде строки в 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), вы уже знаете имя переменной». Я пытаюсь, но я не могу ...
deceze
1
может быть, для этого вы могли бы сохранить переменную, а затем преобразовать ее в json, например, {"instanceA": instanceA} и отправить ее на сервер с помощью вызова ajax или get / post, и что вы можете обработать в php и получить имя экземпляра ...
Geomorillo
@deceze, конечно, вы знаете имя, но это не значит, что вы можете / хотите ввести его вручную. Возможно, вы хотите сбросить кучу переменных для целей отладки, и вам не хочется вручную вводить console.log("myvar = " + myvar);снова и снова для каждой переменной.
Synetech

Ответы:

54

Обычно вы используете хеш-таблицу для ситуации, когда вы хотите отобразить имя на какое-то значение и иметь возможность получить оба.

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

karim79
источник
127
Не отвечает на вопрос, хотя.
Хтафоя
1
@htafoya: Косвенно да - все свойства objпечатаются name: valueпарами. Но поясняющий текст может быть более понятным.
Мэтт
1
@ Я понимаю код, но обычно вопрос OP используется для чего-то более сложного, такого как динамические присваивания, где вы можете выбрать переменную из сгенерированной строки. Или если просто создать словарь для печати значения - это излишне.
htafoya
2
@htafoya - да, что-то простое, как nameof (varname) в C #.
Matt
1
Я думаю, что единственная причина, по которой это «не отвечает на вопрос», заключается в том, что он не начинается с «Вы не можете получить имя константы или переменной в JavaScript. Ближайшая вещь к тому, что вы хотите ...», например этот другой ответ: stackoverflow.com/a/37393679
bigpopakap
86

Как и ответ Сета, но Object.keys()вместо этого используется :

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

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

пончики
источник
5
@titusfx вы можете поменять const на let или var, и он работает точно так же. Но если вы в первую очередь используете транспортер для деструктуризации объекта, он, вероятно, уже поддерживает const.
SethWhite
Кажется, это зависит от использования ES6?
О'Руни
1
@ O'Rooney Да, это специфично для ES6.
Пончики
64

Вы можете использовать следующее решение для решения вашей проблемы:

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

// returns "myFirstName"
Незнакомец
источник
3
Этот ответ похож на [@ SethWhite's] ( stackoverflow.com/a/39669231/5876282 ), но значительно упрощен. Спасибо! @bluejayke Я думаю, что этот ответ приходит спустя годы после первоначального принятого ответа. Но да, в настоящее время это лучшее - за исключением, возможно, использования «pop ()», предложенного ниже
B Charles 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/

SethWhite
источник
1
Отличный ответ !! Это конкретное использование уничтожения объектов является новым для меня (строка 2 let nameObject = {myVar}настолько полезна! Кажется, что это нигде не задокументировано. Есть какие-нибудь ссылки?
Лоренс Лорд
2
@LaurenceLord это называется сокращением свойств. Присвоение свойства объекта без определения (что-то: «asdf») заставит JS определить свойство с именем переменной и ее значением {кое-что} === {кое-что: что-то}. ariya.io/2013/02/…
SethWhite
19
var x = 2;
for(o in window){ 
   if(window[o] === x){
      alert(o);
   }
}

Тем не менее, я думаю, что вы должны сделать как "karim79"

cloverink
источник
8
Это будет работать только в области видимости окна (прерывается, когда внутри функции).
jpillora
1
Согласен - но это наиболее близко к ответу на вопрос ОП. Gj.
Дембински
также, если вы тестируете примитив, он предупредит все переменные, имеющие одинаковое значение, или если двум переменным будет присвоен один и тот же объект. Например, если первая строка была x = 2; y = 2;или x = {a:1}; b = x;это предупредит каждого из них
aljgom
Если вы хотите, чтобы это работало в области действия функции, вы можете попробовать использовать имя функции вместо окна, например: 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);

BrunoLM
источник
2
Это на самом деле работает довольно хорошо! единственная проблема - когда вы передаете что-то вроде этого: nameof (() => options.subOptions.displaySize), который возвращает «subOptions». Вместо этого я использовал это регулярное выражение: exp.toString (). match (/ (? = [^ .] * $) (\ w +) / g) [0]
Джим Браун
Я получаю неопределенный от: var a = {b: "c"}; Оповещение (имя (а)); имя функции (exp) {exp.toString (). match (/ (? = [^.] * $) (\ w +) / g) [0]; } // name
Дэвид Спектор
@JimBrown, спасибо! Ваш комментарий нужно пометить как ответ!
evorios
14

Возможно, pop будет лучше, чем индексирование с помощью [0], для безопасности (переменная может быть нулевой).

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.
Дэвид Спектор
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на любой браузер, в котором я его тестировал, но, согласно комментариям, он работает не везде.

Cadiboo
источник
Ошибка: «Не удается найти переменные ключи»
Александр Волков
ключи не определен
avalanche1
1
это должно быть так, const getVarName = (v) => Object.keys(v)[0];а затем вызывать такую ​​функциюgetVarName({whatEverVariable})
Мадео
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));

Пишет в окошко «домкрат».

Мэтт Смит
источник
2
Это не надежно. В объекте окна может быть любое количество переменных с одинаковым значением.
Тейлор Бьюкенен
2

Вы можете поразмышлять о типах в javascript и получить имя свойств и методов, но то, что вам нужно, это как Lambda Expressions Treesв .NET, я думаю, что это невозможно из-за динамического характера и отсутствия статической системы типов в javascript.

Джахан
источник
3
Я не думаю, что в JS не хватает лямбд или связанных с ними инструментов функционального программирования.
Но я думаю, что в .NET нет структуры, эквивалентной деревьям выражений.
Джахан
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[]команды.

SPRBRN
источник
2
Во втором случае высота - это свойство windowобъекта, потому что переменная с тем же именем была объявлена ​​в области видимости окна. Это работает, только если переменная объявлена ​​в области видимости окна, а не в функции / замыкании.
xoxox
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

Себастьян Нопп
источник
1

Это работало с использованием 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

Данило
источник
Google Chrome 5? действительно??
avalanche1
2
@ avalanche1, согласно таблице совместимости версий MDN.
Данило
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
Не обязательно верно, если код минимизируется;)
Secret
9
Также смысл использования, например, nameof(myVariable)в C # (который возвращает строку «myVariable»), заключается в защите от ошибок при рефакторинге или внесении других изменений в код. Обычный вариант использования - добавить имя переменной в выдаваемое сообщение об ошибке. большинство частей я считаю строковые литералы коды запаха, и подозревает , что именно поэтому по крайней мере , Visual Studio, показывает их в красном / оранжевом цвете , я знаю , я знаю, этот вопрос о Javascript, но я объяснил , почему я закончил здесь..
Merrr
var test = 1235125142; console.log (Object.keys ({test}). pop ()) // "test"
bluejayke
1
@bluejayke Назовите меня невежественным, но через 8 лет я все еще не понимаю, как это лучше, чем console.log('test')когда вам это действительно нужно.
deceze