user7855233
user7855233

Reputation:

Javascript Objects enumeration

What's the difference of putting/changing "property" to this[property] in console, I believe both refer to the same expression but the latter gives me [object, Object] when I call the function.

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"]();

Upvotes: 3

Views: 71

Answers (4)

Pankaj Shukla
Pankaj Shukla

Reputation: 2672

Let's dissect it bit by bit:

rockSpearguns["listGuns"]() call is another way of saying: rockSpearguns.listGuns(); This means the context of "this" is set to rockSpearguns object(at the call site).

When JS tries to evaluate this[property] value, it sees that value of this object is bound to rockSpearguns and "property" is enumerated value of the object property which is string(due to for-in loop). However, this[property] simply means this.property(dot notation). In this case this.property is an object(Sharpshooter etc.) Now when we are trying to concatenate strings, Sharpshooter object needs to be converted to string by calling toString() method which gives back [object, Object].

Upvotes: 1

Martin Adámek
Martin Adámek

Reputation: 18389

When you access this in console or within a simple script, it refers to window, so is the same as accessing variable, which is inside the window scope.

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, 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 about this: http://ryanmorr.com/understanding-scope-and-context-in-javascript/

Upvotes: 1

ibrahim mahrir
ibrahim mahrir

Reputation: 31692

property will be the keys of the object beign looped ("Sharpshooter", "Pokepistol", ...) which are already strings.

this[property] will be the values of the object which are all objects. When concatinating an object with a string the object is cast into a string by calling its function toString. So:

var obj = {};
var string = "Hello. I'm " + obj;

is the same as:

var obj = {};
var string = "Hello. I'm " + obj.toString();

obj.toString() in this case will return "[object Object]".

About bracket and dot notation, here is a the docs on MDN.

Upvotes: 2

Peter Kota
Peter Kota

Reputation: 8340

Inside the for loop the this will be rockSpearGuns object. In this case the this[property] will refer for example the Firefork object. You need to use property instead of this[property].

Try this:

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"]();

Upvotes: 1

Related Questions