89 votes

Obtenir le nom de la propriété de l'objet sous forme de chaîne

Est-il possible d'obtenir le nom de la propriété de l'objet sous forme de chaîne de caractères ?

person = {};
person.first_name = 'Jack';
person.last_name = 'Trades';
person.address = {};
person.address.street = 'Factory 1';
person.address.country = 'USA';

J'aimerais l'utiliser comme ça :

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 Ce code est exactement ce que je recherche. Je comprends que ça semble même stupide, mais ça ne l'est pas.

C'est ce que je veux faire avec.

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 à l'ibu. Il m'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'

DEMO : http://jsbin.com/iyabal/1/edit

0voto

David Points 36241

Vous pourriez créer une méthode d'espacement des noms pour l'objet. La méthode devra faire muter l'objet de sorte que les chaînes deviennent un objet à la place pour contenir deux propriétés, un 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'

Donc maintenant vous pouvez le faire :

var o = { message: MSG_ACTION };
o[ person.first_name._namespace ] = person.first_name.value;

extPort.postMessage(o);

0voto

AmitKB Points 490

Je suis dans la même situation.

Voici ta façon de le faire en utilisant Lodash o UnderScore bibliothèque, avec une limitation de valeur pour être unique :

var myObject = {
'a': 1,
'b': 2,
'c': 3
}
_.findKey(myObject, function( curValue ) { return myObject.a === curValue });

JavaScript pur et 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 fixer 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 )

0voto

Mhd.Tahawi Points 1566

Je suis en retard sur la fête mais j'ai adopté une approche complètement différente. Je vais donc proposer mon approche et voir ce que la communauté en 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é. Je peux obtenir le nom de la propriété (qui est une fonction) à l'aide de la commande .name

Voici un exemple :

person = {
    firstName(){
        return 'John';
    },
    address(){
        return '123 street'
    }
}

person.firstName.name // 'firstName'
person.address.name // 'address'

Note :
Dans ce cas, vous ne pouvez pas facilement modifier la valeur d'une propriété (par exemple le prénom) au moment de l'exécution. vous devrez créer une fonction ( .name serait anonyme dans ce cas) et cette fonction renverrait une nouvelle fonction nommée qui renverrait la nouvelle valeur :

// note the () at the end     
person.firstName = new Function('', 'return function firstName(){return "johny"}')(); 
person.firstName.name ; // 'firstName' 
person.firstName(); // 'johny'

-2voto

Scott Sauyet Points 4228

Non, ce n'est pas possible.

Imaginez ceci :

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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X