-1

I came across this code snippet on Mozilla Developer Network (MDN) and I am racking my brain in trying to figure out why the result would indeed be 'value'

var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {};
object[foo] = 'value';
console.log(object[bar]);

I would be grateful if someone would be so kind as to enlighten me!

3
  • I think it's because it toStringifies object indexers. Commented Nov 3, 2015 at 15:30
  • 2
    Possible duplicate of What does the object[foo] term mean? Commented Nov 3, 2015 at 15:31
  • 3
    The example you linked to gives you your answer: This also outputs "value", since both foo and bar are converted to the same string. In the SpiderMonkey JavaScript engine, this string would be "['object Object']". Commented Nov 3, 2015 at 15:36

5 Answers 5

3
object[foo] = 'value';

You can only have strings as identifiers and hence when the above runs, JavaScript internally calls ToString method, which represents "[object Object]". That's how objects are represented.

Now when you do object[bar], bar.toString() is also "[object Object]", and since 'value' is stored with "[object Object]" as key, it gets returned.

Sign up to request clarification or add additional context in comments.

1 Comment

This has helped a lot ..Cheers Steve
1

If you have a quick look in your console, you will see this is because foo is being coerced into a string (since all keys in Javascript are strings**), which defaults to [object object]. The string [object object] is the same for every object, so foo appears to be bar, but in essence it is not. Check out the below output:

var foo = {unique_prop: 1}, bar = {unique_prop: 2}, object = {};
object[foo] = 'value';

var output = document.getElementById('p')
for(thing in object){
  output.textContent += thing + " = " + object[thing];
}
<p id='p'></p>

** I think that ES6 has a way of setting a computed key using {[func]: value} syntax, but I have not looked into this very deeply yet, so excuse me for the possible incorrectness.

6 Comments

The same answer than @mic4ael but with an explained code. mic4ael has 3 downvotes....
It's worth noting that all object keys are strings in JavaScript.
Per your update, the computed key still results in a string, it's just that they can be generated dynamically in object literals (rather than using bracket notation on an already created object.)
@Mathletics Does that mean they are computed when the object is generated and never again? (If so, then yes, all keys are strings and I will amend :) )
That's my understanding, yes. They are computed when the literal is generated.
|
1

You can see what's going on here with 3 mini experiments:

  1. What is the result of toString() called on each of the objects you create?

    foo.toString(), bar.toString() and object.toString() will output:

    [object Object]
    
  2. What is the result of object[{}]?

    it is also "value", because the key that the runtime used to store your value is literally [object Object]

  3. Let's change the behaviour of toString and see what happens.

    Object.prototype.toString = function(){
      return this.unique_prop;
    };
    
    // Re run the code
    
    object[foo] = "value";
    
    console.log(object[bar]);  // Returns undefined
    
    // Value was stored under the key "1"
    console.log(object[1]);  // Returns "value"
    

Comments

0

Because the key in this object is a string representation of the foo and bar objects, like Object {[object Object]: "value"}.

9 Comments

@Mathletics object[bar] it's an access to a object property as an array
@MarcosPérezGude are you joking, no it isn't. Don't confuse bracket notation with arrays; they are not the same thing.
It's an access to an object property as an array.
I just noticed that I wrote array instead of object. My imission.
Ok, we are misunderstanding. I know that you said. I try to say the same, but we are in an infinite loop LOL!
|
0

As explained above, setting the object property results with an object stringifys the key

> console.log(foo.toString())
[Log] [object Object]

so object[foo] is equivalent to

object["[object Object]"] = 'value';

However if you actually wanted them to be different you could do something like this:

> console.log(JSON.stringify(foo))
[Log] {"unique_prop":1}

> object[JSON.stringify(foo)] = 'donkey'
> console.log(object)
[Log] {[object Object]: "value", {"unique_prop":1}: "donkey"}

> console.log(object[JSON.stringify(bar)])
[Log] undefined

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.