user1282226
user1282226

Reputation:

Javascript: length doesn't work on arrays that are inside an object?

I want to create an object such that object.a is an array while object.b is the length of it and this is what I have:

var object = {
   a:[1,2,3,2],
   b: this.a.length
}
alert(b);

But this won't alert 4. There is something wrong with b: this.a.length:

Uncaught TypeError: Cannot read property 'length' of undefined

I'd be glad if someone can explain to me why this is happening.

It would actaully alert 4 if I write it this way:

 var object = {
       a:[1,2,3,2]
 }
    alert(object.a.length);

[update] even create the object this way, it doesn't work:

var object = {
   a:[1,2,3,2],
   b:object.a.length
}

Upvotes: 0

Views: 1847

Answers (4)

jfriend00
jfriend00

Reputation: 707148

The main problem is that in javascript data declaration like your first example, the value of this is not set to the object being defined. So since this is not your object, this.a inside the object declaration does not refer to the a property of your object.

It is whatever it was in the context right before your data declaration. If that was the global context, then this would be the window object and this.a probably doesn't exist. If it doesn't exist (e.g. it's undefined), then when you try to reference this.a.length, you are trying to read the property .length off something isn't an object and that is a javscript error.


As for solving this problem it is generally a bad idea to copy the length of an array to another property. That just gives you a chance for it to be wrong and out-of-sync with the actual length of the array. If you want the length of the array, you should just retrieve it upon demand with:

object.a.length

If you really want it to be a property (that has a fixed value and doesn't change when a changes), you can set it after you create the object:

var object = {
   a:[1,2,3,2],
};
object.b = object.a.length;
alert(object.b);

Upvotes: 3

pb2q
pb2q

Reputation: 59607

Add b to the object after creating it:

var object = {
    a:[1,2,3,2]
}

object.b = object.a.length

Upvotes: 0

jbabey
jbabey

Reputation: 46647

all properties of an object are instantiated at once, so this refers to the window object when creating the property b. You'd need to defer the interpretation of b's value, one way is to use a function instead:

var object = {
    a:[1,2,3,2],
    b: function () {
        return this.a.length;
    }
}

Another way is to add the property b after the object literal has been declared:

var object = {
    a:[1,2,3,2]
}
object.b = object.a.length;

Finally, on newer browsers you can take advantage of a getter:

var object = {
    a:[1,2,3,2],
    get b() {
        return this.a.length;            
    }
}

Upvotes: 1

Victor
Victor

Reputation: 5107

In the first example 'b' is undefined, because it is looking for a variable named 'b' not the property 'b' inside of the object 'object'. You should use object.b instead.

Upvotes: 0

Related Questions