shafty
shafty

Reputation: 605

Can't access item in a javascript associative array

I have a javascript "module" (as we call them in python) in a file called thing.js:

function Thing(){
this.a = "foo";
this.b = "bar";
this.c = "";

this.d = function(){
    this.c = this.a + this.b;
};
};

var things = {
'one':Thing(),
'two':Thing(),
'three':Thing()
};
alert(things["one"]); // output: undefined!!??

/* Pick out two random items from things. */
var random_thing = function(){
    //var grabbed = 0;
    //while(grabbed < 1){
var pick = getRandomInt(0,2);
alert(things["one"]); // output: undefined!!
    //if ()
    //return pick;
};

The code is a little incomplete, I want to randomly pick out two items from things and return them. That's not the immediate issue though.

I have a separate "main" javascript file called main.js, which calls to these objects and functions:

$div1.append(random_thing());

In my html file, I include both javascript files:

<script type="text/javascript" src="thing.js"></script>
<script type="text/javascript" src="main.js"></script>

But the output I keep getting is "undefined" for alert(things['one'])! I don't understand how the first alert returns undefined, it's right below the definition of the things associative array.

Upvotes: 0

Views: 136

Answers (1)

Hubro
Hubro

Reputation: 59323

Calling Thing() will do nothing for you other than mangling the window properties. You're looking for new Thing()

var things = {
    'one': new Thing(),
    'two': new Thing(),
    'three': new Thing()
};

If you call a "class" function without using the new keyword, then this will refer to the window global object, which virtually ensures that things will go wrong - some times terribly so. When you do use the new keyword, this will refer to a brand new object that will be returned automatically.

This is a common issue with JavaScript "classes" and is (in my opinion) best avoided by using creator functions:

function Thing() {
    this.a = "foo";
    this.b = "bar";
    this.c = "";

    this.d = function(){
        this.c = this.a + this.b;
    };
};
Thing.create = function() {
    return new Thing();
};

var things = {
    'one': Thing.create(),
    'two': Thing.create(),
    'three': Thing.create()
};

The goal here is to never rely on the new keyword outside of the creator functions.

Upvotes: 3

Related Questions