var foo = {prop:1};
var bar = {prop:2};
var obj = {};
obj[foo] = 'value';
console.log(obj[bar]); //'value'
It is quite confusing why obj[bar] and obj[foo] are same now, whereas foo and bar are not same.
because
obj[foo]='value';
is the same as
obj["[object Object]"]='value';
Object keys are string so it's internally doing foo.toString()
and foo.toString() === bar.toString()
Every objects will return "[object Object]" if used as a key (not talking about arrays, numbers, strings..)
You'll need something that uniquely identify your objects, like below
var foo = {id:"foo", prop:1};
var bar = {id:"bar", prop:2};
var obj = {};
obj[foo.id] = 'value';
console.log(obj[bar.id]); //undefined
Related
While practising few examples , I encountered the following example :
var foo = {unique_prop: 1};
var bar = {unique_prop: 2};
var object = {};
object[foo] = 'value';
alert(object[bar]);
where two objects foo and bar are created . I am not getting how alert(object[bar]); is "value".
Whats the link here between foo and bar.
Also, a slight variation would give the output as "undefined" as the example below.
var foo = {unique_prop: 1};
var bar = {unique_prop: 2};
var object = {};
object["foo"] = 'value';
alert(object[bar]);
By default , the [] notation can use the strings right , arent ["some_property"] and [some_property] the same?
When using square bracket notation, anything inside the square brackets is converted into a string. Then that string is used to look for a property called the same thing.
var foo = {unique_prop: 1};
var bar = {unique_prop: 2};
var object = {};
object[foo] = 'value';
// foo is an object, so it's automatically turned into the string "[object Object]"
// so the above code is equivalent to `object["[object Object]"] = 'value';`
alert(object[bar]);
// bar is also an object, so is converted into the same string
// the above code is also equivalent to `alert(object["[object Object]"]);` which of course accesses that same value
var blah = "not blah";
object.blah = 1;
object["blah"] = 1;
object[blah];
// a variable is used.
// therefore the value of that variable is what the assessor is looking for, not the name of the variable.
// so the above code is equivalent to `object["not blah"];`.
An object's keys can only be strings*, so when you access an object's property using value which is not a string, it gets converted to a string.
In ECMAScript 6 you can use Map, which is similar to objects, but you can use any value as a key. Example:
const foo = {unique_prop: 1}
const bar = {unique_prop: 2}
const map = new Map()
map.set(foo, 'value')
console.log(map.get(bar)) // undefined
* In ECMAScript 6 you can also use symbols, but that's not relevant here.
The question is similar to this: How do I interpolate a variable as a key in a JavaScript object?
However, I have a difficult on using variables on nth keys:
I had a object, which is:
var object = {};
object.foo = "foo";
object.foo.bar = "bar";
object.foo.bar.alice = "alice";
object.foo.bar.alice.bob = "bob";
I am able to get the value (foo) for object.foo by using the variable object["foo"]
But I cannot find out a way to access to object.foo.bar value.
I tried object["foo"]["bar"], but it does not work.
In addition to my question, how can I get the value for
object.foo.bar.alice
object.foo.bar.alice.bob
By using variable as well?
Thanks.
You need an object for foo, because foo is a primitive type.
var object = {};
object.foo = "foo";
object.foo.bar = "bar"; // does not work!
This works
var object = {};
object.foo = {};
object.foo.bar = "bar"; // work!
When you do
var object = {};
object.foo = "foo";
You define the property as string and it won't store the keys since it is a string literal not a string object.
you need to try
var object = {};
object.foo = new String("foo");
Now it can store more properties in object.foo.
var object = {};
object.foo = new String( "foo" );
object.foo.bar = new String( "bar" );
object.foo.bar.alice = new String( "alice" );
object.foo.bar.alice.bob = new String( "bob" );
console.log( object );
you need to assign as a object {key:value,key:value}
object.foo = {0:"foo",bar:{}};
object.foo.bar = {0:"bar",alice:{}};
object.foo.bar.alice = {0:"alice",bob:{}};
object.foo.bar.alice.bob = "bob";
console.log(object.foo.bar.alice);
console.log(object.foo.bar.alice.bob);
You can develop a simple function to get the nested objects and their keys dynamically. Such as the following. A similar approach would be sufficient for the set version as well.
Object.prototype.getNestedValue = function(...a) {
return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};
var arr = [{fox: [{turn:[857, 432]}]}, {sax: [{pana:[777, 987]}]}, {ton: [{joni:[123, 567]}]}, {piu: [{burn:[666, 37]}]}, {sia: [{foxy:[404, 696]}]}],
myObj = {foo: {bar: {alice: {bob: "bob"}}}};
document.write("<pre>" + JSON.stringify(arr.getNestedValue(3,"piu",0,"burn",1),null,2) + "</pre>");
document.write("<pre>" + JSON.stringify(arr.getNestedValue(3,"piu",0,"burn"),null,2) + "</pre>");
document.write("<pre>" + JSON.stringify(myObj.getNestedValue("foo","bar","alice","bob"),null,2) + "</pre>");
Keep in mind that you can set your nested properties in an array in the order of appearance and then call like myDeeplyNestedObj.getNestedValue(...propsArray)
Not sure what to search for here, so apologies if I'm repeating another question.
I'm wondering if there are any issues that I'm not aware of with using the following syntax in JavaScript:
var a = {};
var b = a.niceCoat = {};
Seems handy, but I just want to make sure...
That is perfectly fine, because a was declared previously. The expressions will be evaluated as
var a = {};
var b = (a.niceCoat = {});
I.e. it first assigns a new empty object to a.niceCoat and the result (the result of an assignment is the assigned value) to b.
But be aware of something like
var a = b = 'c';
which, again, is evaluated as
var a = (b = 'c');
Only a will be in local scope, b would be global. If you want b to be local too, you have to declare it beforehand: var b;. Something like var a = var b = .... does not work (not valid syntax).
Slightly off topic:
This method is indeed handy. Imaging you have an object of objects, something like:
var map = {
foo: {},
bar: {}
};
and you want to get the object for a certain key or create a new one if the key does not exists. Normally one would probably do:
var obj = map[key];
if(!obj) { // works because if the key is set, it is an object
obj = {}; // which evals to true
map[key] = obj;
}
// now work with obj
With the above method, this can be shortened to
var obj = map[key];
if(!obj) {
map[key] = obj = {};
}
And we can make it even shorter with the logical OR operator (||):
var obj = map[key] || (map[key] = {});
(though it might be less readable).
You can do that. a.niceCoat = {} will be evaluated first, which assigns the object to the property and also has the object as result, which you then can assign to the variable.
You should however be aware that b and a.niceCoat are now referencing the same object, so if you put anything in the object it will show up for both the variable and the property:
var a = {};
var b = a.niceCoat = {};
b.x = 42;
alert(a.niceCoat.x); // shows 42
There no issue with that. It's the same as:
var b = (a.niceCoat = {});
Which is the same as:
a.niceCoat = {};
var b = a.niceCoat; // Now b and a.niceCoat are the same object
Just be careful with declaring entirely new variables with it like:
var i = j = 0;
Which is the same as:
j = 0;
var i = j;
Notice how j is not declared with the var keyword.
this is how you create an empty object in javascript. nothing wrong with it.
Yep, absolutely valid.
E.g.
var a = {};
var b = a.niceCoat = {};
a.foo = function() { alert('foo!'); };
a.foo(); // shows the alert
More specifically, how would you determine if a certain object was created using a literal or not?
var s1 = new String();
var s2 = ""; // Literal
var o1 = new Object();
var o2 = {}; // Literal
var f1 = new Function();
var f2 = function(){}; // Literal
Obviously if you compare any two above, for example:
var o1 = new Object();
var o2 = {};
alert(o1 == o2);
alert(o1 === o2);
alert(typeof o1);
alert(typeof o2);
... The first two alerts will show false while the last two alerts will give [Object object]
Say for example, if I wanted to do this:
function isLiteral(obj, type) {
// ...
}
... how would one go about doing this?
I have taken a look at How to determine if an object is an object literal in Javascript?, but it does not answer my question.
Firstly, the difference between these two lines:
var s1 = new String();
var s2 = ""; // Literal
...and the difference between these two lines:
var o1 = new Object();
var o2 = {}; // Literal
...are two different concepts.
The first is the difference between a primitive value and an object, while the second is... different syntax for the same thing.
Strings, numbers and booleans are primitive values, not objects, but can be wrapped as objects using new String(), new Number() or new Boolean(). So for these, typeof will return different values:
var s1 = new String();
typeof s1; // "object"
var s2 = "";
typeof s2; // "string"
However, for Object and Function, the difference between:
var o1 = new Object();
var o2 = {};
... is in syntax only.
Both o1 and o2 have the same prototype, and the same constructor, making them indistinguishable at runtime.
Set an object, with some data.
var blah = {};
blah._a = {};
blah._a._something = '123';
Then wish to try and access, how would I go about doing this correctly?
var anItem = 'a';
console.log(blah._[anItem]);
console.log(blah._[anItem]._something);
The bracket notation should look like this:
var anItem = 'a';
console.log(_glw['_'+anItem]);
console.log(_glw['_'+anItem]._something);
You can test it here (note that I replaced _glw with blah in the demo to match the original object).
Not sure I understand the question, but here are some basics.
var foo = {};
// These two statements do the same thing
foo.bar = 'a';
foo['bar'] = 'a';
// So if you need to dynamically access a property
var property = 'bar';
console.log(foo[property]);
var obj = {};
obj.anotherObj = {};
obj.anotherObj._property = 1;
var item = '_property';
// the following lines produces the same output
console.log(obj.anotherObj[item]);
console.log(obj.anotherObj['_property']);
console.log(obj.anotherObj._property);