Nazwa zmiennej jako ciąg znaków w JavaScript


154

Czy istnieje sposób, aby uzyskać nazwę zmiennej jako ciąg znaków w JavaScript? (jak NSStringFromSelectorw kakao )

Chciałbym zrobić tak:

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

--> myFirstName:John

AKTUALIZACJA

Próbuję połączyć przeglądarkę i inny program za pomocą JavaScript. Chciałbym wysłać nazwy instancji z przeglądarki do innego programu dla metody wywołania zwrotnego:

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

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

...

Z innego programu:

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

W PHP: Jak uzyskać nazwę zmiennej jako ciąg znaków w PHP?


2
@delnan Rzeczywiście, +1. Nie przychodzi mi do głowy inny sposób ujęcia tego niż „jeśli potrafisz pisać variablesName(myFirstName), znasz już nazwę zmiennej”. Próbuję, ale nie mogę ...
— zamrozić


1
może w tym celu mógłbyś zapisać w zmiennej i później przekonwertować ją na json, na przykład {"instanceA": instanceA} i wysłać do serwera przy użyciu ajax lub wywołania get / post i że możesz przetworzyć w php i uzyskać nazwę instancji ...
— Geomorillo

@deceze, oczywiście, znasz nazwę, ale to nie znaczy, że możesz / chcesz wpisać ją ręcznie. Może chcesz zrzucić kilka zmiennych do celów debugowania i nie masz ochoty ręcznie wpisywać console.log("myvar = " + myvar);w kółko każdej zmiennej.
— Synetech

Odpowiedzi:


54

Zwykle użyłbyś tabeli skrótów w sytuacji, w której chcesz zmapować nazwę na jakąś wartość i móc pobrać obie.

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


125
Nie odpowiada jednak na pytanie.
— htafoya,

1
@htafoya: Pośrednio, tak - wszystkie właściwości objsą drukowane jako name: valuepary. Ale tekst wyjaśniający mógłby być bardziej przejrzysty.
— Matt

1
@Mat Rozumiem kod, ale generalnie pytanie OP jest używane do czegoś bardziej złożonego, jak przypisania dynamiczne, w których można wybrać zmienną z wygenerowanego ciągu. Lub gdzie zwykłe utworzenie słownika do wydrukowania wartości jest przesadą.
— htafoya

2
@htafoya - tak, coś prostego jak nameof (varname) w C #.
— Matt

1
Myślę, że jedynym powodem, dla którego to „nie odpowiada na pytanie” jest to, że nie zaczyna się od „Nie możesz uzyskać nazwy stałej lub zmiennej w JavaScript. Najbardziej zbliżona do tego, czego chcesz ...”, na przykład ta inna odpowiedź: stackoverflow.com/a/37393679
— bigpopakap

86

Podobnie jak odpowiedź Setha, ale Object.keys()zamiast tego używa :

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

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


5
@titusfx możesz zamienić const na let lub var i działa tak samo. Ale jeśli używasz transpilera do niszczenia obiektów w pierwszej kolejności, prawdopodobnie obsługuje on już const.
— SethWhite

Wydaje się, że zależy to od używania ES6?
— O'Rooney

1
@ O'Rooney Tak, to jest specyficzne dla ES6.
— Donuts

63

Aby rozwiązać problem, możesz skorzystać z następującego rozwiązania:

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

// returns "myFirstName"

3
Ta odpowiedź jest podobna do [@ SethWhite's] ( stackoverflow.com/a/39669231/5876282 ), ale jest znacznie uproszczona. Dzięki! @bluejayke Myślę, że ta odpowiedź pojawia się wiele lat później po pierwotnie zaakceptowanej odpowiedzi. Ale tak, obecnie jest to najlepsze - może z wyjątkiem użycia „pop ()” sugerowanego poniżej
— B Charles H

1
czy można zrobić funkcję, która przyjmie zmienną i wypisze jej nazwę? Próbowałem zawinąć twój kod w funkcję, ale id zwrócił mi nazwę, która została użyta jako argument
— Wakan Tanka

@WakanTanka Jeśli utworzysz właściwe pytanie, odpowiem tam.
— Fellow Stranger

@WakanTanka nie, to nie zadziała. Jak odkryłeś, po prostu wypisze nazwę, którą podasz argumentowi funkcji. Myślę, że warto zobaczyć, jak taka funkcja skompilowałaby się do starszej specyfikacji Javascript. W tym przykładzie ( jsfiddle.net/bigpopakap/wq891ghr/2 ) widać, że składnia {zmienna} jest po prostu skrótem od {zmienna: zmienna}, więc nie można użyć nazwy zmiennej z funkcji wywołującej
— bigpopakap

42

W ES6 można by napisać coś takiego:

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

Nie najlepiej wyglądająca rzecz, ale spełnia swoje zadanie.

Wykorzystuje to niszczenie obiektów w ES6.

Więcej informacji tutaj: https://hacks.mozilla.org/2015/05/es6-in-depth-destruifying/


1
Świetna odpowiedź!! To szczególne zastosowanie niszczenia obiektów jest dla mnie nowe (wiersz 2 jest let nameObject = {myVar}bardzo przydatny! Nie wydaje się być nigdzie udokumentowany. Masz jakieś linki?
— Laurence Lord

2
@LaurenceLord nazywa się to skrótem właściwości. Przypisanie właściwości obiektu bez definicji (coś: „asdf”) spowoduje, że JS zdefiniuje właściwość z nazwą zmiennej i jej wartością {coś} === {coś: coś}. ariya.io/2013/02/…
— SethWhite

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

Jednak myślę, że powinieneś lubić „karim79”


8
Będzie to działać tylko w zakresie okna (przerwy, gdy wewnątrz funkcji).
— jpillora

1
Zgoda - ale najbliżej odpowiedzi na pytanie PO. Gj.
— Dembinski

również jeśli testujesz prymityw, zaalarmuje wszystkie zmienne, które mają tę samą wartość lub jeśli dwie zmienne mają przypisany ten sam obiekt. Na przykład, jeśli pierwszym wierszem był x = 2; y = 2;lubx = {a:1}; b = x; ostrzegłaby każdego z nich
— aljgom

Jeśli chcesz, aby to działało w zakresie funkcji , możesz spróbować użyć nazwy funkcji zamiast okna, na przykład: var foo = function f(){ f.x = 2; for(o in f){ if(f[o]===f.x) alert(o); } } wtedy wywołanie f()ostrzeże
— ``

1
@aljgom - dobra uwaga. Tutaj jest skrzypce do wypróbowania.
— Matt

16

Działa to w przypadku podstawowych wyrażeń

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

Przykład

nameof(() => options.displaySize);

Skrawek:

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


2
To działa całkiem nieźle! jedynym problemem jest to, że przekazujesz coś takiego: nameof (() => options.subOptions.displaySize), która zwraca "subOptions" Zamiast tego użyłem tego wyrażenia regularnego: exp.toString (). match (/ (? = [^ .] * $) (\ w +) / g) [0]
— Jim Brown

Jestem niezdefiniowany z: var a = {b: "c"}; alert (nazwa (a)); nazwa funkcji (exp) {exp.toString (). match (/ (? = [^.] * $) (\ w +) / g) [0]; } // nazwa
— David Spector

@JimBrown, dziękuję! Twój komentarz musi być oznaczony jako odpowiedź!
— evorios,

14

Prawdopodobnie pop byłby lepszy niż indeksowanie z [0] ze względów bezpieczeństwa (zmienna może być zerowa).

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

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

3
Jeśli myFirstName jest przekazywana do funkcji (zawierającej ten kod) jako argument v, wówczas nazwa zmiennej jest raportowana jako v zamiast myFirstName.
— David Spector

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

Nie można tego przekształcić w funkcję, ponieważ zwraca nazwę zmiennej funkcji.

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

Edycja: Podziękowania dla @Madeo za wskazanie, jak uczynić to funkcją .

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

Będziesz musiał wywołać funkcję z pojedynczą tablicą elementów zawierającą zmienną. debugVar({somefancyvariable});
Edycja: Object.keysmożna odwoływać się tak, jak keysw każdej przeglądarce, w której go testowałem, ale zgodnie z komentarzami nie działa wszędzie.


Błąd: „Nie można znaleźć kluczy zmiennych”
— Alexander Volkov

klucze nie są zdefiniowane
— lawina 1

1
powinno być tak, const getVarName = (v) => Object.keys(v)[0];a następnie wywołaj tę funkcję w ten sposóbgetVarName({whatEverVariable})
— Madeo

6

Od ECMAScript 5.1 możesz używać Object.keys do pobierania nazw wszystkich właściwości z obiektu.

Oto przykład:

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

Kiedy funkcja jest zapisywana w funkcji, która zmienia wartości różnych zmiennych globalnych, nie zawsze jest to moje pierwsze imię, lecz jest to coś, przez co przechodzi. Spróbuj, to zadziałało dla mnie.

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

Napiszę do okna „jack”.


2
To nie jest wiarygodne. W obiekcie window może znajdować się dowolna liczba zmiennych o tej samej wartości.
— Taylor Buchanan

2

Możesz zastanowić się nad typami w javascript i uzyskać nazwy właściwości i metod, ale to, czego potrzebujesz, to coś takiego jak Lambda Expressions Treesw .NET, myślę, że nie jest to możliwe ze względu na dynamiczny charakter i brak statycznego systemu typów w javascript.


3
Nie sądzę, aby JSowi brakowało lambd lub powiązanych narzędzi programowania funkcjonalnego.

Ale myślę, że nie ma struktury odpowiadającej drzewom wyrażeń w .NET.
— Jahan

2

Potrzebowałem tego, nie chcę używać obiektów i wymyśliłem następujące rozwiązanie, odwracając pytanie.

Zamiast zamieniać nazwę zmiennej na ciąg, konwertuję ciąg na zmienną.

Działa to tylko wtedy, gdy znana jest nazwa zmiennej.

Weź to:

var height = 120;
testAlert(height);

Powinno to wyświetlić:

height: 120

Można to zrobić w następujący sposób:

function testAlert(ta)
{
    a = window[ta];
    alert(ta + ': ' + a); 
}

var height = 120;
testAlert("height");
// displays: height: 120

Więc używam ciągu "height"i zamieniam go w zmienną heightza pomocą window[]polecenia.


2
W drugim przypadku wysokość jest właściwością windowobiektu, ponieważ zmienna o tej samej nazwie została zadeklarowana w zakresie okna. Działa to tylko wtedy, gdy zmienna jest zadeklarowana w zakresie okna, a nie w funkcji / zamknięciu.
— xoxox,

2

Krótkie sposoby, które znalazłem do tej pory, aby uzyskać nazwę zmiennej jako ciąg:

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

Stworzyłem tę funkcję w oparciu o JSON, jak ktoś zasugerował, działa dobrze dla moich potrzeb debugowania

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

Nie, nie ma.
Poza tym, jeśli potrafisz pisać variablesName(myFirstName), znasz już nazwę zmiennej („myFirstName”).


11
Niekoniecznie prawda, jeśli kod jest zminimalizowany;)
— Secret

9
Celem używania np. nameof(myVariable)W C # (który zwraca ciąg „myVariable”) jest ochrona przed błędami podczas refaktoryzacji lub wprowadzania innych zmian w kodzie. Typowym przypadkiem użycia jest dodanie nazwy zmiennej do generowanego komunikatu o błędzie. większość części, które uważam za dosłowne napisy, pachną kodem i podejrzewam, że właśnie dlatego przynajmniej Visual Studio pokazuje je w kolorze czerwono-pomarańczowym. Wiem, wiem, to pytanie dotyczy JavaScript, ale właśnie wyjaśniłem, dlaczego tutaj skończyłem.
— merrr

var test = 1235125142; console.log (Object.keys ({test}). pop ()) // "test"
— bluejayke

1
@bluejayke Nazywaj mnie ignorantem, ale po 8 latach wciąż nie rozumiem, jak to jest lepsze niż console.log('test')lub kiedy naprawdę tego potrzebujesz.
— deceze
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.