Ім'я змінної як рядок у 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 або отримати / подзвонити, і ви можете обробити в php і отримати ім'я екземпляра ...
Геоморілло,

@deceze, звичайно, ви знаєте ім'я, але це не означає, що ви можете / хочете ввести його вручну. Можливо, ви хочете скинути купу змінних для налагодження і не відчуваєте, як вручну вводити console.log("myvar = " + myvar);знову і знову для кожної змінної.
Synetech

Відповіді:


54

Як правило, ви використовуєте хеш-таблицю для ситуації, коли ви хочете зіставити ім'я з деяким значенням і зможете отримати обидва.

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


125
Однак не відповідає на питання.
хтафоя

1
@htafoya: Побічно, так - всі властивості objдрукуються як name: valueпари. Але текст, що пояснює, міг бути більш зрозумілим.
Метт

1
@Mat Я розумію код, але, як правило, питання ОП використовується для чогось більш складного, як динамічних призначень, де ви можете вибрати змінну з генерованого рядка. Або там, де просто створити словник для друку значення - це надмірність.
хтафоя

2
@htafoya - так, щось таке, як nameof (varname) у C #.
Метт

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?
O'Rooney

1
@ O'Rooney Так, це специфічно для ES6.
Пончики

63

Ви можете використовувати таке рішення для вирішення своєї проблеми:

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

// returns "myFirstName"

3
Ця відповідь схожий на [@ SethWhite - х] ( stackoverflow.com/a/39669231/5876282 ) , але значно спрощена. Дякую! @bluejayke Я думаю, що ця відповідь приходить через роки після оригінальної прийнятої відповіді. Але так, на даний момент це найкраще - за винятком можливо запропонованого нижче
B Charles H

1
чи можна зробити функцію, яка буде приймати змінну та надрукувати її ім'я? Я спробував зафіксувати ваш код всередині функції, але id повернув мені ім'я, яке було використано як аргумент
Wakan Tanka

@WakanTanka Якщо ви створите належне запитання, я відповім на нього.
товариш незнайомця

@WakanTanka ні, це б не працювало. Як ви виявили, він буде просто надрукувати ім'я, яке ви даєте аргументу функції. Я думаю, що це допомагає зрозуміти, як така функція збиратиметься до старої специфікації Javascript. Ви можете побачити в цьому прикладі ( jsfiddle.net/bigpopakap/wq891ghr/2 ), що синтаксис {змінної} просто короткий для {змінної: змінної}, тому неможливо використовувати ім'я змінної з функції виклику
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}настільки корисний! Він, здається, ніде не задокументований. Маєш посилання?
Лоренс Лорд

2
@LaurenceLord це називається скороченням властивостей. Призначення властивості об’єкта без визначення (щось: 'asdf'), призведе до того, що JS визначить властивість з назвою змінної та її значенням {щось} === {щось: щось}. ariya.io/2013/02/…
SethWhite

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

Однак, я думаю, вам слід зробити так, як "karim79"


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


2
Це насправді працює досить добре! Єдина проблема полягає в тому, що ви передаєте щось подібне: nameof (() => options.subOptions.displaySize), який повертає "subOptions" Натомість я використав цей регекс: exp.toString (). match (/ (? = [^ .] * $) (\ w +) / g) [0]
Джим Браун

Я не визначаюсь з: var a = {b: "c"}; оповіщення (ім’я (а)); назва функції (exp) {exp.toString (). матч (/ (? = [^.] * $) (\ w +) / g) [0]; } // ім’я
Девід Спектор

@JimBrown, дякую! ваш коментар потрібно позначити як відповідь!
evorios

14

Можливо, поп буде кращим, ніж індексація з [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, тоді зміннийName повідомляється як 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на кожен браузер, на який я тестував, але згідно з коментарями, він працює не скрізь.


Помилка: "Неможливо знайти змінні ключі"
Олександр Волков,

ключі не визначений
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

Коли функція записує функцію, яка змінює різні значення глобальних змінних, це не завжди моє ім'я, це все, що трапляється. Спробуйте це працювало для мене.

Виконати в 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[]команди.


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.
danilo

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 # (який повертає рядок "myVariable", є захист від помилок під час рефакторингу або внесення інших змін до коду. Загальний випадок використання - додавання імені змінної до повідомлення про помилку, яке викидається. Для більшість частин я вважаю рядкові літерали коди запаху, і підозрює , що саме тому по крайней мере , Visual Studio, показує їх в червоному / помаранчевому кольорі , я знаю , я знаю, це питання про Javascript, але я пояснив , чому я закінчив тут ..
merrr

вар тест = 1235125142; console.log (Object.keys ({test}). pop ()) // "тест"
bluejayke

1
@bluejayke Називай мене невігласом, але через 8 років я все ще не бачу, як це краще, ніж console.log('test')тоді, коли тобі це справді потрібно.
деге
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.