9

For example I have such an object:

var a = {
    'light': 'good',
    'dark' : {
        'black': 'bad',
        'gray' : 'not so bad'
    }
}

and such a code:

var test = function(obj) {
    // do smth with object
    // I need to get obj's name ('dark' in my way)
}
test(a.dark);

How to get name of object in function's body. So I mean I should know that obj's name is 'dark'.

I've tried inspect object with firebug, but it's only show object's property. It's not showing some internal methods or properties, with which I'll be able to know

Thank you.

Larry Foobar
  • 11,092
  • 15
  • 56
  • 89
  • Refer to this question: http://stackoverflow.com/questions/722668/traverse-all-the-nodes-of-a-json-object-tree-with-javascript . It explaines how to get the object name and values. – Abdel Raoof Olakara Mar 27 '11 at 08:45

6 Answers6

19

You can't. You're only passing the object { black : 'bad', gray : 'not so bad' } into test. This object does not intrinsically have the name "dark", it's just an object that happened to exist as the property dark of the object a. This information is irretrievably lost when passing it into a function.

You're basically trying to retrieve the variable name that held the value before the value got passed into the function. That's not possible.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 3
    +1 Objects and variables are two totally different beasts, each object is referred to by 0 to infinity variables and doesn't/shouldn't know anything about any of them. –  Mar 27 '11 at 08:51
  • Ok. It's a pitty (for me in such case). I've understood – Larry Foobar Mar 27 '11 at 08:53
4

The "name of an object" is no intrinsic property of an object. A "name" is name in a given context. When you pass an object to a function, then you just pass that object, not the context in which it was named ("dark" in your example).

Whatever you want to accomplish, you are on the wrong track.

Frunsi
  • 7,099
  • 5
  • 36
  • 42
  • I just keep some configs in objects, and I wanted to make less properties in it (for example 'type' property getting from name but not from object property 'type') – Larry Foobar Mar 27 '11 at 09:10
3

I would like to point you to the possibility to iterate through an object and recursively find the name of the parent of some property. With it your test function would look like:

var test = function(rootobj,propname,rootObjName) {
    // do smth with object AS rootobj[propname]
    var objparents = findParents(rootobj,propname,rootObjName);
}
test(a,'dark','a');

Where findParents is:

function findParents(obj,key,rootName){
 var parentName = rootname || 'ROOT', result = [];
 function iterate(obj, doIndent){
  var parentPrevName = ''
  for (var property in obj) {
    if (obj.hasOwnProperty(property)){

        if (obj[property].constructor === Object) {
           parentPrevName = parentName;
           parentName = property;
           iterate(obj[property]);
           parentName = parentPrevName;
        }
        if (key === property) {
                result.push('Found parent for key ['
                             +key+' (value: '+obj[property]
                             +')] => '+parentName);
        }

    }
  }
 }
 iterate(obj);
 return result;
}

The problem of course is that a property wouldn't have to be unique. As in:

var a = 
{
    'light': 'good',
    'dark' : {
        'black': 'bad',
        'gray' : 'not so bad'
        'yellow' : {
                     'dark': 'will do', //<=there's 'dark' again!
                     'light':'never use'
                   }
    }
}

Well, may be it's usable. You can find a demo of the findParents function in http://jsfiddle.net/KooiInc/Kj2b9/

KooiInc
  • 119,216
  • 31
  • 141
  • 177
2

It is possible with :

function loadProps(obj, container) {
    for (var p in obj) {
        container.push(p);
        if (obj[p].constructor == Object) {
            loadProps(obj[p], container);
        }
    }
}

then :

var props = [];
loadProps(a, props);

console.log( props.join(",") );
Frederik.L
  • 5,522
  • 2
  • 29
  • 41
2

var a = { name:'a', 'light': 'good', 'dark' : { name: 'dark', 'black': 'bad', 'gray' : 'not so bad' } }

This way you can do

console.log(a.name,a.dark.name);
0

This might be a little silly approach, but you can include a new key with the value of the Object Name.

obj = {objName: "obj"}

It worked for me. Let me know if that helps.