Enumerating Javascript Objects
What's the difference in setting / changing "property"
to this[property]
in the console, I believe both refer to the same expression, but the latter gives me [object, Object] when the function is called.
var rockSpearguns = {
Sharpshooter: {barbs: 2, weight: 10, heft: "overhand"},
Pokepistol: {barbs: 4, weight: 8, heft: "shoulder"},
Javelinjet: {barbs: 4, weight: 12, heft: "waist"},
Firefork: {barbs: 6, weight: 8, heft: "overhand"},
"The Impaler": {barbs: 1, weight: 30, heft: "chest"}
};
rockSpearguns["listGuns"] = function(){
for (var property in this) {
if(this[property]["heft"]!==undefined){
console.log("Behold! " + this[property] + ", with " +
this[property]["heft"] + " heft!");
}
}
}
rockSpearguns["listGuns"]();
source to share
property
will be the key object looped beign ( "Sharpshooter"
, "Pokepistol"
, ...), which are already strings.
this[property]
will be the object values that are all objects. When you concatenate an object with a string, the object is passed to the string by calling its function toString
. So:
var obj = {};
var string = "Hello. I'm " + obj;
matches:
var obj = {};
var string = "Hello. I'm " + obj.toString();
obj.toString()
in this case will return "[object Object]"
.
About brackets and dot notation, here's a doc on MDN .
source to share
When you access this
in the console or in a simple script, it refers to window
, as well as accessing a variable that is inside the scope window
.
var a = 123; // variable `a` is bound to `window`
console.log(a); // 123
console.log(window.a); // 123
console.log(this.a); // 123
But when you are inside a function or object, it this
refers to its own context:
function test () {
this.a = 123;
console.log(a); // 123
console.log(this.a); // 123
console.log(this); // test {a: 123}
}
new test(); // to create new context for this function, we need to call `new`, otherwise it will also be `window`
console.log(typeof a); // undefined
console.log(this.a); // undefined
console.log(this); // window
More on this: http://ryanmorr.com/understanding-scope-and-context-in-javascript/
source to share
Inside the loop, the for
object this
will be rockSpearGuns
. In this case, it this[property]
will refer to, for example, an object Firefork
. You need to use property
instead this[property]
.
Try the following:
var rockSpearguns = {
Sharpshooter: {barbs: 2, weight: 10, heft: "overhand"},
Pokepistol: {barbs: 4, weight: 8, heft: "shoulder"},
Javelinjet: {barbs: 4, weight: 12, heft: "waist"},
Firefork: {barbs: 6, weight: 8, heft: "overhand"},
"The Impaler": {barbs: 1, weight: 30, heft: "chest"}
};
rockSpearguns["listGuns"]=function(){
for (var property in this) {
if(this[property]["heft"]!==undefined){
console.log("Behold! " + property + ", with " +
this[property]["heft"] + " heft!");
}
}
}
rockSpearguns["listGuns"]();
source to share
Let's cut it in half:
rockSpearguns["listGuns"]()
calling is another way of saying: rockSpearguns.listGuns (); This means that the "this" context has a rockSpearguns object set (at the calling site).
When JS tries to evaluate this [property] value, it sees that the value of this object is bound to rockSpearguns, and "property" is the enumerated value of the property of the object, which is a string (due to the in-in loop). However, this [property] simply means this.property (dot notation). In this case, this.property is an object (Sharpshooter, etc.), Now when we try to concatenate strings, the Sharpshooter object needs to be converted to a string by calling the toString () method, which returns [object, Object].
source to share