Est-il possible d'obtenir le nom de la propriété de l'objet sous forme de chaîne
person = {};
person.first_name = 'Jack';
person.last_name = 'Trades';
person.address = {};
person.address.street = 'Factory 1';
person.address.country = 'USA';
Je voudrais l'utiliser comme ceci:
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'
Merci d'avance
NOTE: ce code correspond exactement à ce que je recherche. Je comprends que cela semble même stupide, mais ce n’est pas le cas.
C'est ce que je veux en faire.
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
}
};
----------------------RÉPONSE--------------------- -
Je l'ai eu grâce à ibu. Il a indiqué le bon chemin et j'ai utilisé une fonction récursive
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'
Oui, vous pouvez, avec un peu de changement.
function propName(prop, value){
for(var i in prop) {
if (prop[i] == value){
return i;
}
}
return false;
}
Maintenant, vous pouvez obtenir la valeur comme suit:
var pn = propName(person,person.first_name);
// pn = "first_name";
Remarque Je ne suis pas sûr de savoir à quoi il peut être utilisé.
Autre Remarque ne fonctionnera pas très bien avec les objets imbriqués. mais là encore, voir la première note.
Je connais une pratique exemplaire qui consiste à utiliser Object.keys (votre_objet) . Il analysera le nom de la propriété du tableau pour vous. Exemple:
var person = { firstName: 'John', lastName: 'Cena', age: '30' };
var listPropertyNames = Object.keys(person); //["firstName", "lastName", "age"]
J'espère que cet exemple vous sera utile.
Vous pouvez envelopper votre propriété dans une fonction, puis la convertir en chaîne et en extraire la propriété.
Par exemple:
function getPropertyName(propertyFunction) {
return /\.([^\.;]+);?\s*\}$/.exec(propertyFunction.toString())[1];
}
Puis l'utiliser:
var myObj = {
myProperty: "testing"
};
getPropertyName(function() { myObj.myProperty; }); // myProperty
Méfiez-vous que les minificateurs pourraient casser cela.
Edit: J'ai créé une transformation de compilateur qui fonctionne avec Babel et le compilateur TypeScript (voir ts-nameof ). C'est beaucoup plus fiable que de faire quelque chose au moment de l'exécution.
Vous pouvez accomplir cela en convertissant toutes les propriétés de l'objet en fonctions qui renverront leurs propres noms.
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'
Pour donner suite à la réponse de @David Sherret avec ES6, cela peut être rendu très simple:
propName = f => /\.([^\.;]+);?\s*\}$/.exec(f.toString())[1]
let prop = propName(() => {obj.name}); // myProperty
Je suis en retard à la fête, mais j’ai adopté une approche complètement différente, je vais donc donner mon avis et voir ce que la communauté pense.
J'ai utilisé Function.prototype.name
pour faire ce que je veux . Mes propriétés sont des fonctions qui, lorsqu'elles sont appelées, renvoient la valeur de la propriété, et je peux obtenir le nom de la propriété (qui est une fonction) en utilisant .name
Voici un exemple:
person = {
firstName(){
return 'John';
},
address(){
return '123 street'
}
}
person.firstName.name // 'firstName'
person.address.name // 'address'
Remarque:
vous ne pouvez pas facilement changer la valeur d’une propriété (par exemple, prenom) au moment de l’exécution dans ce cas . vous auriez besoin de créer une fonction (.name
serait anonyme dans ce cas) et cette fonction renverrait un nouvelle fonction nommée qui renvoie la nouvelle valeur:
// note the () at the end
person.firstName = new Function('', 'return function firstName(){return "johny"}')();
person.firstName.name ; // 'firstName'
person.firstName(); // 'johny'
Je suis dans la même situation.
Voici comment vous pouvez le faire en utilisant Lodash ou UnderScore library, avec une limite de valeur unique:
var myObject = {
'a': 1,
'b': 2,
'c': 3
}
_.findKey(myObject, function( curValue ) { return myObject.a === curValue });
JavaScript simple
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 )
Mais, je préférerais corriger le code comme solution. Un exemple:
var myObject = {
'a': {key:'a', value:1},
'b': {key:'b', value:2},
'c': {key:'c', value:3}
}
console.log( myObject.a.key )
Non, ce n'est pas possible.
Imagine ça:
person.age = 42;
person.favoriteNumber = 42;
var pn = propName(person.age)
// == propName(42)
// == propName(person.favoriteNumber);
La référence au nom de la propriété est simplement perdue dans ce processus.
Je le préfère propre et simple comme ça:
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
}
Vous pouvez créer une méthode de nommage pour l'objet. La méthode devra muter l'objet afin que les chaînes deviennent un objet contenant deux propriétés, une value
et un _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'
Alors maintenant, vous pouvez faire:
var o = { message: MSG_ACTION };
o[ person.first_name._namespace ] = person.first_name.value;
extPort.postMessage(o);