Is it possible to get the object property name as a string
person = {};
person.first_name = \'Jack\';
person.last_name = \'Trades\';
person.address = {};
per
You could create a namespacing method for the object. The method will need to mutate the object so that the strings becomes an object instead to hold two properties, a value
and a _namespace
.
DEMO: http://jsfiddle.net/y4Y8p/1/
var namespace = function(root, name) {
root._namespace = name;
function ns(obj) {
for( var i in obj ) {
var a = obj._namespace.split('.')
if ( a.length ) {
a.push(i);
}
if( typeof obj[i] == 'object' ) {
obj[i]._namespace = a.join('.');
ns(obj[i]);
return;
}
if( typeof obj[i] == 'string' ) {
var str = obj[i].toString();
obj[i] = {
_namespace: a.join('.'),
value: str
};
}
}
}
ns(root);
};
namespace(person, 'person');
console.log(person.address.street._namespace) // person.address.street
console.log(person.address.street.value) // 'Factory 1'
So now you can do:
var o = { message: MSG_ACTION };
o[ person.first_name._namespace ] = person.first_name.value;
extPort.postMessage(o);
Following up on @David Sherret's answer with ES6 it can be made super simple:
propName = f => /\.([^\.;]+);?\s*\}$/.exec(f.toString())[1]
let prop = propName(() => {obj.name}); // myProperty
I prefer it clean and simple like this:
var obj = {
sessionId: 123,
branchId: 456,
seasonId: 789
};
var keys = Object.keys(obj);
for (var i in keys) {
console.log(keys[i]); //output of keys as string
}
I am late to the party but I took a completely different approach, so I will throw in my approach and see what the community thinks.
I used Function.prototype.name to do what I want.
my properties are functions that when called return the value of the property, and I can get the name of the property (which is a function) using .name
Here is an example:
person = {
firstName(){
return 'John';
},
address(){
return '123 street'
}
}
person.firstName.name // 'firstName'
person.address.name // 'address'
Note:
you can't easily change the value of a property (e.g firstname) at run time in this case.
you would need to create a function (.name
would be anonymous in this case) and this function would return a new named function which return the new value:
// note the () at the end
person.firstName = new Function('', 'return function firstName(){return "johny"}')();
person.firstName.name ; // 'firstName'
person.firstName(); // 'johny'
I use the following in TypeScript. This way retains type-information and disallows selecting non-existing property keys.
export function getPropertyName<T extends object>(obj: T, selector: (x: Record<keyof T, keyof T>) => keyof T): keyof T {
const keyRecord = Object.keys(obj).reduce((res, key) => {
const typedKey = key as keyof T
res[typedKey] = typedKey
return res
}, {} as Record<keyof T, keyof T>)
return selector(keyRecord)
}
I am in same situation.
Here is thy way to get it done using Lodash or UnderScore library, with one limitation of value to be unique:
var myObject = {
'a': 1,
'b': 2,
'c': 3
}
_.findKey(myObject, function( curValue ) { return myObject.a === curValue });
Plain JavaScript
function getPropAsString( source, value ){
var keys = Object.keys( source );
var curIndex,
total,
foundKey;
for(curIndex = 0, total = keys.length; curIndex < total; curIndex++){
var curKey = keys[ curIndex ];
if ( source[ curKey ] === value ){
foundKey = curKey;
break;
}
}
return foundKey;
}
var myObject = {
'a': 1,
'b': 2,
'c': 3
}
getPropAsString( myObject, myObject.a )
But, I would prefer to fix the code as solution. An example:
var myObject = {
'a': {key:'a', value:1},
'b': {key:'b', value:2},
'c': {key:'c', value:3}
}
console.log( myObject.a.key )