Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 10 of 10
  1. #1
    New to the CF scene
    Join Date
    Mar 2010
    Posts
    8
    Thanks
    0
    Thanked 1 Time in 1 Post

    Using objects as object-keys

    Hi all,

    I was under the impression that I and object/associative array could have other objects as the keys for properties. That is, I should be able to set myObject[anotherObject] = 1. However, while this seems to work at first glance, any new object I set as a property key overwrites the first one.

    Here is the result of me testing in my Chrome console:
    Code:
    > var obj1 = new Object();
    > var obj1.someProperty = "test"
    "test"
    > var obj2 = new Object();
    > obj2.someOtherProperty = "test2"
    "test2"
    > obj1 == obj2
    false
    > obj1 === obj2               // the two objects I created are definitely not the same
    false
    > x = {}
    > x[obj1] = 0                   // set the two objs as property keys on x
    0
    > x[obj2] = 1
    1
    > x[obj1]
    1                                     // blargh! x.obj2 overwrote x.obj1!
    Any idea if this is possible, and if I'm just messing up with something dumb?

  • #2
    New to the CF scene
    Join Date
    Mar 2010
    Posts
    8
    Thanks
    0
    Thanked 1 Time in 1 Post
    D'oh! I worked it out.

    Javascript allows you to set objects as keys, but silently transforms them to strings using toString() when it does so.

    So if obj1.toString() and obj2.toString() return the same thing (which they would by default), there is no difference between x.obj1 and x.obj2.

    The solution is to define a toString method that will return unique strings for each object.

  • #3
    Kor
    Kor is offline
    Red Devil Mod Kor's Avatar
    Join Date
    Apr 2003
    Location
    Bucharest, ROMANIA
    Posts
    8,478
    Thanks
    58
    Thanked 379 Times in 375 Posts
    An object is, in javascript, an unordered list of pairs name:value (members)

    The value may be: a string, a number, an array, an object or a Boolean
    The name may be only a string. Even it is not written as a string (and this way is not a recommended), in a literal construction it is automatically considered as a string.

    In your example you try to create a pair name:value where name is an object, which is not allowed (except when that object is a function which returns a string).

    So, you problem has no solution. Or better say you have created a false problem. The moment you write the object (say obj1) as a string ("obj2") you get, in fact two different entities (an object and a string) which have no relationship as they are. The only case in which you may discover a relationship, is when you refer that global object (obj2) as a property of the Window Global Object: window['obj2'], which is not the case of your problem.
    Last edited by Kor; 03-17-2011 at 04:31 PM.
    KOR
    Offshore programming
    -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

  • #4
    Regular Coder Krupski's Avatar
    Join Date
    Dec 2010
    Location
    United States of America
    Posts
    505
    Thanks
    39
    Thanked 47 Times in 46 Posts
    Quote Originally Posted by Kor View Post
    An object is, in javascript, an unordered list of pairs name:value (members)

    The value may be: a string, a number, an array, an object or a Boolean
    The name may be only a string. Even it is not written as a string (and this way is not a recommended), in a literal construction it is automatically considered as a string.
    Since you seem to understand this, let me ask you a question... something I've been trying to work out but haven't been successful yet:

    I understand this: var test = { 'name' : 'object' };

    And I understand test[name] == 'object'

    But since "object" can be an object, is THIS legal:

    var test = { 'a' : { 'b' : 'c' }};

    ...or this...

    var test = { 'a' : { 'b' : { 'c' : 'd' }}};

    ...and if so, how does one access the various parts?

    What I'm ultimately after is a construct something like this:

    Code:
    var smilies = {
        ':lol:'   : './images/laughing.gif' : 'Laughing out loud!',
        ':sad:'   : './images/crying.gif'   : 'Sadly crying',
        .......
        .......
    }
    Then be able to access any property of one line (for example above, the smiley code, the smiley URL or the smiley hover description).

    I want a big array of smiley info that I can loop through to generate one long string of HTML.

    Any input will be appreciated! Thanks!

    -- Roger
    "Anything that is complex is not useful and anything that is useful is simple. This has been my whole life's motto." -- Mikhail T. Kalashnikov

  • #5
    Kor
    Kor is offline
    Red Devil Mod Kor's Avatar
    Join Date
    Apr 2003
    Location
    Bucharest, ROMANIA
    Posts
    8,478
    Thanks
    58
    Thanked 379 Times in 375 Posts
    once again: the value of an object member can be an Object as well

    maybe this will help you understand:
    http://json.org
    KOR
    Offshore programming
    -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

  • Users who have thanked Kor for this post:

    Krupski (03-18-2011)

  • #6
    New to the CF scene
    Join Date
    Mar 2010
    Posts
    8
    Thanks
    0
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Kor View Post
    So, you problem has no solution.
    Since the problem I was trying to solve was basically "how can I create an associative array wich binds values to object keys," I don't think it's quite right that the problem had no solution. Rather, I just had to be aware that, when I thought I was using objects, I was actually using the toString version of the object.

    Then it was simply a matter of ensuring the toString method would always return a unique value for each object.

    It may be true, though, that's it's still bad form even to write x[obj1], even if I know it's using strings under the hood, and that instead I should be writing x[obj1.toString()] to make it explicit.
    Last edited by SamSam; 03-17-2011 at 10:00 PM.

  • #7
    New to the CF scene
    Join Date
    Mar 2010
    Posts
    8
    Thanks
    0
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Krupski View Post

    But since "object" can be an object, is THIS legal:

    var test = { 'a' : { 'b' : 'c' }};

    ...or this...

    var test = { 'a' : { 'b' : { 'c' : 'd' }}};

    ...and if so, how does one access the various parts?
    Yes, those are both legal. In order to access the value 'd' you could refer to it by test.a.b.c. The first nested object is test.a. The next nested object is test.a.b -- that is, get the "b" property of object "test.a". Finally, get the "c" property of that, test.a.b.c, which is "d".

    alert(test.a.b.c)
    > d

    You could also refer to it as test['a']['b']['c'].

    What I'm ultimately after is a construct something like this:

    Code:
    var smilies = {
        ':lol:'   : './images/laughing.gif' : 'Laughing out loud!',
        ':sad:'   : './images/crying.gif'   : 'Sadly crying',
        .......
        .......
    }
    Then be able to access any property of one line (for example above, the smiley code, the smiley URL or the smiley hover description).

    I want a big array of smiley info that I can loop through to generate one long string of HTML.
    Sure this is possible:

    Code:
    var smilies = {
       "lol": {
                 "url": './images/laughing.gif',
                 "longName": 'Laughing out loud!'
                },
       "sad": {
                 "url": './images/crying.gif',
                 "longName": 'Sadly crying'
                }
       }
    
    alert(smilies.lol.url)
     > ./images/laughing.gif
    alert(smilies.sad.longName)
     > Sadly crying
    To cycle through properties, if you don't know what properties exist, you can either use 'for (i in smilies){}' notation, or look at something like jQuery.each().
    Last edited by SamSam; 03-17-2011 at 10:05 PM.

  • Users who have thanked SamSam for this post:

    Krupski (03-18-2011)

  • #8
    Kor
    Kor is offline
    Red Devil Mod Kor's Avatar
    Join Date
    Apr 2003
    Location
    Bucharest, ROMANIA
    Posts
    8,478
    Thanks
    58
    Thanked 379 Times in 375 Posts
    Quote Originally Posted by SamSam View Post
    and that instead I should be writing x[obj1.toString()] to make it explicit.
    Not exactly:

    Notations like
    Code:
    object.property
    or
    Code:
    object['property']
    are, most of the time, equivalent. No need for toString() by all means

    I still don't understand what you are looking for...
    KOR
    Offshore programming
    -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

  • #9
    Regular Coder Krupski's Avatar
    Join Date
    Dec 2010
    Location
    United States of America
    Posts
    505
    Thanks
    39
    Thanked 47 Times in 46 Posts
    Quote Originally Posted by Kor View Post
    maybe this will help you understand:
    http://json.org
    OMG! So simple. Now I clearly understand the difference between an object and an array. The graphical representation that site has made it all clear. THANK YOU!!!

    -- Roger
    "Anything that is complex is not useful and anything that is useful is simple. This has been my whole life's motto." -- Mikhail T. Kalashnikov

  • #10
    Regular Coder Krupski's Avatar
    Join Date
    Dec 2010
    Location
    United States of America
    Posts
    505
    Thanks
    39
    Thanked 47 Times in 46 Posts
    Quote Originally Posted by SamSam View Post
    Yes, those are both legal. In order to access the value 'd' you could refer to it by test.a.b.c. The first nested object is test.a. The next nested object is test.a.b -- that is, get the "b" property of object "test.a". Finally, get the "c" property of that, test.a.b.c, which is "d".
    Thanks... seeing that (bold in your quote) I'm getting it (I think). Let me try this:

    My "test" example is like a box. Inside the box is a box labeled "a". Inside "a" is "b" and inside "b" is "c" and inside "c" is "d". Each box (including the main box) is an OBJECT.

    I can access "a" simply by opening the main box (i.e. test.a).

    The "value" of test.a is an object called "b" which "contains" c and d.

    To get at b, I have to open the main box and box "a" (test.a.b).

    Inside box b is another object... a box named c that contains d.

    ..etc...

    If this is right... then I FINALLY get it! (it is right... right?)....
    "Anything that is complex is not useful and anything that is useful is simple. This has been my whole life's motto." -- Mikhail T. Kalashnikov


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •