ชื่อตัวแปรเป็นสตริงใน Javascript


154

มีวิธีรับชื่อตัวแปรเป็นสตริงใน Javascript หรือไม่? (เหมือนNSStringFromSelectorในโกโก้ )

ฉันต้องการทำสิ่งนี้:

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

--> myFirstName:John

UPDATE

ฉันพยายามเชื่อมต่อเบราว์เซอร์และโปรแกรมอื่นโดยใช้ 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 call และคุณสามารถประมวลผลใน 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]);


126
ไม่ตอบคำถาม
htafoya

1
@htafoya: ทางอ้อมใช่ - คุณสมบัติทั้งหมดของobjจะพิมพ์เป็นname: valueคู่ แต่ข้อความอธิบายอาจมีความชัดเจนมากขึ้น
แมตต์

1
@Mat ฉันเข้าใจโค้ด แต่โดยทั่วไปคำถาม OP จะใช้สำหรับสิ่งที่ซับซ้อนกว่าเป็นการกำหนดแบบไดนามิกที่คุณสามารถเลือกตัวแปรจากสตริงที่สร้างขึ้น หรือที่ที่เพียงสร้างพจนานุกรมเพื่อพิมพ์ค่ามากเกินไป
htafoya

2
@htafoya - ใช่ง่าย ๆ อย่าง nameof (varname) ใน C #
Matt

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

ดูเหมือนว่าจะขึ้นอยู่กับการใช้ 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 ฉันคิดว่าคำตอบนี้มาหลายปีต่อมาหลังจากคำตอบเดิมที่ยอมรับ แต่ใช่ปัจจุบันนี้ดีที่สุด - ยกเว้นการใช้งาน "pop ()" ที่แนะนำด้านล่าง
B Charles H

1
เป็นไปได้ไหมที่จะสร้างฟังก์ชั่นที่จะยอมรับตัวแปรและพิมพ์ชื่อได้? ฉันได้ลองห่อโค้ดของคุณด้วยฟังก์ชั่นแล้ว แต่ id ส่งคืนฉันชื่อซึ่งใช้เป็นอาร์กิวเมนต์
Wakan Tanka

@WakanTanka ถ้าคุณสร้างคำถามที่เหมาะสมฉันจะตอบมันที่นั่น
Fellow Stranger

@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}มีประโยชน์มาก! ดูเหมือนว่าจะไม่มีการบันทึกไว้ที่ใด ๆ มีการเชื่อมโยงใด ๆ บ้างหรือไม่
ลอเรนซ์ลอร์ด

2
@ LaurenceLord มันเรียกว่าชวเลขคุณสมบัติ การกำหนดคุณสมบัติของวัตถุโดยไม่มีคำนิยาม (บางอย่าง: 'asdf') จะทำให้ JS กำหนดคุณสมบัติด้วยชื่อของตัวแปรและค่าของมัน {some} === {something: something} ariya.io/2013/02/…
SethWhite

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

อย่างไรก็ตามฉันคิดว่าคุณควรทำเช่น "karim79"


8
สิ่งนี้จะทำงานที่ขอบเขตหน้าต่างเท่านั้น (หยุดพักเมื่ออยู่ภายในฟังก์ชัน)
jpillora

1
เห็นด้วย - แต่ใกล้เคียงที่สุดกับการตอบคำถามของ OP Gj
Dembinski

หากคุณกำลังทดสอบพื้นฐานมันจะแจ้งเตือนตัวแปรทั้งหมดที่มีค่าเท่ากันหรือหากตัวแปรสองตัวมีวัตถุเดียวกันที่กำหนดให้กับพวกเขา ตัวอย่างเช่นถ้าบรรทัดแรกเป็น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" แทนฉันใช้ regex นี้: exp.toString (). match (/? = [^ .] * $) (\ w +) / g) [0]
Jim Brown

ฉันไม่ได้กำหนดจาก: var a = {b: "c"}; การแจ้งเตือน (ชื่อ (ก)); ชื่อฟังก์ชัน (exp) {exp.toString (). match (/ (? = [^.] * $) (\ w +) / g) [0]; } // name
David Spector

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

เมื่อมีฟังก์ชั่นเขียนฟังก์ชั่นที่เปลี่ยนค่าตัวแปรทั่วโลกที่แตกต่างกันมันไม่ได้ชื่อ myfirst เสมอมันเป็นสิ่งที่เกิดขึ้นที่จะผ่าน ลองใช้วิธีนี้ใช้ได้กับฉัน

ทำงานใน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

คุณสามารถนึกถึงประเภทในจาวาสคริปต์และได้รับชื่อของคุณสมบัติและวิธีการ แต่สิ่งที่คุณต้องการคือ sth เหมือนLambda Expressions Treesใน. NET ฉันคิดว่ามันเป็นไปไม่ได้เนื่องจากลักษณะที่เป็นแบบไดนามิกและการขาดระบบประเภทสแตติกในจาวาสคริปต์


3
ฉันไม่คิดว่า JS ขาด lambdas หรือเครื่องมือการเขียนโปรแกรมที่เกี่ยวข้อง

แต่ฉันคิดว่าไม่มีโครงสร้างเทียบเท่ากับ Expression Trees ใน. 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

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" เพื่อป้องกันข้อผิดพลาดเมื่อ refactoring หรือการเปลี่ยนแปลงอื่น ๆ รหัสกรณีการใช้งานทั่วไปคือการเพิ่มชื่อของตัวแปรในข้อความข้อผิดพลาดที่ถูกโยนสำหรับ ส่วนใหญ่ฉันคิดว่าสตริงกลิ่นตัวอักษรรหัสและสงสัยว่าเป็นเหตุผลที่อย่างน้อย Visual Studio แสดงให้พวกเขาในสีแดง / ส้มฉันรู้ว่าฉันรู้ว่าคำถามนี้เป็นเรื่องเกี่ยวกับ Javascript แต่ฉันเพิ่งอธิบายว่าทำไมฉันสิ้นสุดที่นี่
merrr

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

1
@bluejayke โทรหาฉันไม่รู้ แต่หลังจาก 8 ปีฉันก็ยังล้มเหลวที่จะดูว่ามันดีกว่าconsole.log('test')หรือเมื่อคุณต้องการมันจริงๆ
หลอกลวง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.