Get object property name as a string
Solution 1
Yes you can, with a little change.
function propName(prop, value){
for(var i in prop) {
if (prop[i] == value){
return i;
}
}
return false;
}
Now you can get the value like so:
var pn = propName(person,person.first_name);
// pn = "first_name";
Note I am not sure what it can be used for.
Other Note wont work very well with nested objects. but then again, see the first note.
Solution 2
I know a best practice that using Object.keys(your_object). It will parse to array property name for you. Example:
var person = { firstName: 'John', lastName: 'Cena', age: '30' };
var listPropertyNames = Object.keys(person); //["firstName", "lastName", "age"]
I hope this example is useful for you.
Solution 3
You can accomplish this by converting all object properties into functions which will return the their own names
var person = {};
person.firstname = 'Jack';
person.address = "123 Street";
function getPropertyName(obj, expression) {
var res = {};
Object.keys(obj).map(k => { res[k] = () => k; });
return expression(res)();
}
let result = getPropertyName(person, o => o.address);
console.log(result); // Output: 'address'
Solution 4
If anyone's looking for a TypeScript version of MarsRobot's answer, try this:
function nameof<T>(obj: T, expression: (x: { [Property in keyof T]: () => string }) => () => string): string
{
const res: { [Property in keyof T]: () => string } = {} as { [Property in keyof T]: () => string };
Object.keys(obj).map(k => res[k as keyof T] = () => k);
return expression(res)();
}
Usage:
const obj = {
property1: 'Jim',
property2: 'Bloggs',
property3: 'Bloggs',
method: () => 'a string',
child: { property4: 'child1' }
};
const test1 = nameof(obj, x => x.property1);
const test2 = nameof(obj, x => x.property2);
const test3 = nameof(obj, x => x.method);
const test4 = nameof(obj.child, x => x.property4);
console.log(test1); // -> 'property1'
console.log(test2); // -> 'property2'
console.log(test3); // -> 'method'
console.log(test4); // -> 'property4'
This version works even when objects have multiple properties with the same value (unlike some of the other answers above), and with editors like Visual Studio will provide intellisense for the property names when you get here: nameof(obj, x => x.
Solution 5
You can wrap your property in a function and then convert the function to a string and get the property out of it.
For example:
function getPropertyName(propertyFunction) {
return /\.([^\.;]+);?\s*\}$/.exec(propertyFunction.toString())[1];
}
Then to use it:
var myObj = {
myProperty: "testing"
};
getPropertyName(function() { myObj.myProperty; }); // myProperty
Beware that minifiers could break this.
Edit: I have created a compiler transform that works with babel and the typescript compiler (see ts-nameof). This is a much more reliable than doing something at runtime.
Related videos on Youtube
CLiFoS
Updated on September 20, 2021Comments
-
CLiFoS over 2 years
Is it possible to get the object property name as a string
person = {}; person.first_name = 'Jack'; person.last_name = 'Trades'; person.address = {}; person.address.street = 'Factory 1'; person.address.country = 'USA';
I'd like to use it like this:
var pn = propName( person.address.country ); // should return 'country' or 'person.address.country' var pn = propName( person.first_name ); // should return 'first_name' or 'person.first_name'
NOTE: this code is exactly what I'm looking for. I understand it sounds even stupid, but it's not.
This is what I want to do with it.
HTML
person = {}; person.id_first_name = 'Jack'; person.id_last_name = 'Trades'; person.address = {}; person.address.id_address = 'Factory 1'; person.address.id_country = 'USA'; extPort.postMessage ( { message : MSG_ACTION, propName( person.first_name ): person.first_name } };
----------------------ANSWER-----------------------
Got it thanks to ibu. He pointed the right way and I used a recursive function
var res = ''; function propName(prop, value) { for (var i in prop) { if (typeof prop[i] == 'object') { if (propName(prop[i], value)) { return res; } } else { if (prop[i] == value) { res = i; return res; } } } return undefined; } var pn = propName(person, person.first_name); // returns 'first_name' var pn = propName(person, person.address.country); // returns 'country'
-
RonaldBarzell over 11 yearsI'm confused... why do you want the property name to return the same thing you fed it? You already know the property name then... If you're looking for a way to iterate through properties, you can use the bracket notation and loop through the keys, as properties are also hash indices
-
Šime Vidas over 11 yearsYou need to also pass a reference to the object into the function.
-
I Hate Lazy over 11 yearsNot automatically. The string referenced by
country
property doesn't know anything about theaddress
object, and the object referenced by theaddress
property doesn't know anything about theperson
object. -
CLiFoS over 11 yearsI understand this can be confusing, but that is exactly what I need. I need the property name as a string tough
-
Christophe over 11 yearsso you actually mean var pn = propName("USA");
-
Šime Vidas over 11 yearsI'd love to help, but jsFiddle is currently unresponsive
-.-
-
CLiFoS over 11 yearsno. the code I posted is what I need. basically, the prop name is the ID of the page element and I want to get it to use it.
-
I Hate Lazy over 11 yearsYou need to explicitly pass them as separate values.
-
Jason over 11 yearsYou want to use the ID to get the prop, or the prop to get the ID?
-
Jason over 11 years@Šime CodePen.io is better than jsFiddle anyway ;)
-
Christophe over 11 yearsYou really need to clarify your question, maybe add the html sample. Look at the answers, 4 people have 4 different interpretations!!!
-
Jason L. over 11 yearsYour code sample won't work as you're actually just passing the value of that property, not some reference to the property. Your first example would pass 'USA' to the function which is not useful for your desired result.
-
Aerik over 11 yearsDo you want to do this just because you like the coding style, or are you working wtih some existing unchangeable code that you need to use this way? What are your constraints?
-
Scott Sauyet over 11 yearsAnd jsbin.com/iyabal/2/edit shows the flaw with this approach.
-
Christophe over 11 years-1 Sorry, your code is really a bad practice. See this example: jsbin.com/iyabal/4/edit ... and en.wikipedia.org/wiki/Nestor_Burma as a reference ;-)
-
CLiFoS over 11 yearsyes, you are both right and I have doped this line of thinking. I'm sending an array as a parameter now, and it's working fine. thanks anyway.
-
Nic about 9 yearspossible duplicate of JavaScript: Getting the object's property name
-
RationalDev likes GoFundMonica almost 8 yearsThis would be useful instead of passing strings around representing a object property name. You could then have static checking, refactoring or mangling.
-
Alain DENIS about 7 years
-
Alain DENIS about 7 yearsautomatic name property for a created object you could have a look at that example.. ;)
-
Caltor over 4 yearsCan you delete your answer out of the question please. If you want to answer your own question post an actual answer below so others can vote on it.
-
Chris over 2 yearsTell me you want to use typescript without telling me you want to use typescript.
-
-
Sampson over 11 yearsThis assumes that no two properties will have the same value in an object.
-
CLiFoS over 11 yearsyour function returns 'first_name' if you pass person.first_name but if you use person.address.street returns false. maybe using it recursively?
-
Jason Sperske over 11 yearsI was fascinated by this answer so I started hacking away at it to try and find a cleaner approach. here is what I've come up with so far, what do you think: jsfiddle.net/y4Y8p/17
-
David Hellsing over 11 years@JasonSperske nice, but it’s not recursive so it only works 3 levels deep: jsfiddle.net/y4Y8p/18
-
Jason Sperske over 11 yearsjsfiddle.net/y4Y8p/22 try it now :) There are still larger problems, like it takes all values and casts them to strings, but this is a fun bit of code to play with
-
Vladislav over 5 yearsIt is the best solution!
-
Moha the almighty camel about 5 years@Please_Dont_Bully_Me_SO_Lords, Hence the sentence: "my properties are functions that when called return the value of the property"
-
Moha the almighty camel about 5 yearsand that's why I made it clear in my answer: 1- I am taking a different approach, 2- my properties are functions, 3- I have a note about how you should update the value of a property. By no means I am suggesting that this is the best approach, I am just proposing a way to do what OP wants to do. In his example it is a string because he is using plain attributes, in my approach I am wrapping them in functions. OP can use my answer to add wrapper around his attributes. My attributes are functions syntactically, yes. but, semantically, my attributes are the result of the function call,
-
Moha the almighty camel about 5 years@Please_Dont_Bully_Me_SO_Lords, if you see anyway this answer can be improved, please be my guest. Thank you.
-
Florian Leitgeb over 4 yearsAnd how do you get a specific key?
-
Maximilian Fixl over 4 yearsWhy shoult Object.keys return a specific key? The point from that question was, to get the key of an object as a string!? Or not? I‘m confused now...
-
Florian Leitgeb over 4 yearsYes, but you iterate over ALL keys. There is no chance getting a specific property name with your solution.
-
Maximilian Fixl over 4 yearsAh, I got it! No, my solution is only for all keys, you‘re right. I misunderstood the question.
-
saygley almost 4 yearsIf you see warning about "no return value"; here is the modified version: Object.keys(obj).map(k => { res[k] = () => k; return k;});
-
tno2007 almost 4 yearsDo you have a simple example how to use this method?
-
MadSkunk about 3 yearsFYI I've added a TypeScript version below if anyone's looking for one.
-
SMUsamaShah almost 3 yearsWhy does even this work
console.log(propName({}).first_name);
? -
SMUsamaShah almost 3 yearsThis fails when properties have same value.
-
Digital Alpha over 2 yearsthis will give a wrong result in case the value of 2 keys are the same. ex:
person = {old: 25, name:'John', age: 25}; propName(person, person.age); // return "old"
-
Digital Alpha over 2 yearsthis does not answer the question, as it will return an array of the keys. the answer should return one string value
-
Keslavi about 2 yearssmh... everything triet said but add .join()
-
Luminous about 2 yearsTo get rid of the "No index signature with a parameter of type ...." error, you need to add
as keyof T
tores[k]
. It would beres[k as keyof T]
. Suggested edit queue is full else I'd add this to the answer myself.