1

Array defines length=0 if the indexes are non numeric.

I came across this implementation of getting length but still i fear to use for in loop for arrays. Most of the places for in loop is instructed as 'bad practice'. see here

Is it okay to implement like this?

Can someone provide alternate solution(without for in loop)?

any example with for loop?

I have used hasOwnProperty(..) method to avoid properties of Array.prototype.

Array.prototype.global = 1;

var arr = [];
arr['first'] = 1;
arr['second'] = 2;

console.log(arr.length);  //0

var length = 0;
for(index in arr){
   if(arr.hasOwnProperty(index)) {length++;}
}

console.log(length); //3
Community
  • 1
  • 1
P K
  • 9,972
  • 12
  • 53
  • 99
  • 1
    See here: http://stackoverflow.com/questions/5223/length-of-javascript-associative-array – jValdron Jan 05 '12 at 18:12
  • I am pretty sure that the for loop is necessary. You may be able to find some function that does the same, but I'm sure under the hood it still has to loop. Whats your reason for not wanting the loop? – Sean Thoman Jan 05 '12 at 18:14
  • 1
    See the edit of the original poster: JavaScript does not have associative arrays -- it only has objects. So what you are doing there is basically an object, not an array. You could say arr.first and get 1 or arr.second and get 2. – jValdron Jan 05 '12 at 18:14
  • 1
    What's the matter with using a loop? There _are_ other solutions proposed there, BTW. – Matt Ball Jan 05 '12 at 18:14
  • Arrays are not associative, you are adding object properties, that's why you get arr.length = 0 instead of 3, you should use var arr = {} instead of []. – javiertoledos Jan 05 '12 at 18:16
  • @ jValdron I know array is an object, but my question is something else, should i use for in loop or not? if yes for my implementation. i am okay. if not any alternative? – P K Jan 05 '12 at 18:17
  • and of course hasownproperty is a method of Object.prototype, so array can use that BUT i am asking any alternative to for in. – P K Jan 05 '12 at 18:20
  • @Javier what's the relation or [] or {} with my question? can you please describe? Arrays are anyways a type of object. – P K Jan 05 '12 at 18:21
  • 1
    @Praveen is just for concepts, as the answer of stephen suggest, if you are not using an Array as an numerical array but an associative one, you can avoid getting the properties of Array.prototype, and you can get the length with Object.keys(arr).length, of course Object.keys is not supported by all browsers, see [this question](http://stackoverflow.com/questions/5223/length-of-javascript-associative-array) for the ways to get the lengh of an "associative array" – javiertoledos Jan 05 '12 at 18:58
  • @Praveen one more thing, in the answer you listed is considered bad practice use a loop only if you need to take care about the order of the elements and if you don't use an object literal (Array.prototype instead {} in this case), you only need to know the length, don't be affraid to use a loop to count the elements. – javiertoledos Jan 05 '12 at 19:07

1 Answers1

5

You're not using an array as an array anymore in your example. Arrays in JS are (strictly speaking) only a bunch of stuff like this:

['a', 'b', 'c']

What you've done is started to use the empty array as an object.. the [ ] simple accesses a property via a string/variable... so

var obj = {test: 'blah'}
obj['test'] //is 'blah'
obj.test //is also blah

Generally the [ ] notation is used when you're going to access properties or methods via a variable or if the property or method is not something that is 'safe'.. for instance 'int'.

So, change what you have into an object and then step through the keys with a 'for in' loop. Yes, you'll still have to check on each one to see if it hasOwnProperty (or use a jquery/underscore 'each'), but at least you'll be using the right tool for the job :) Or if you just want the count of keys, underscore.js has a nice little _.keys method.. so _.keys(obj).length would give you the number of keys. Pretty sure it's just local keys, not prototype ones..

Edit: as a re-read and hopefully better to the point answer, there is no property in JS that I'm aware of where you can simply get a count of the keys. If it was just a particular thing you were working with and not 'all object's, you could do something like..

var specialObject = function () {this.keys = 0;};
specialObject.prototype.set = function (key, val)  {
    if(!this[key]) {
       this.keys++;
    }
    this[key] = val;
};
var so = new specialObject();
so.set('test', 'blah');
so.keys //would be 1
so.test //would be 'blah'

and then just always use 'set'. You'd want to make an 'unset' and possibly a 'get' method as well.

Hopefully this all makes sense.. it's a bit rambly.

Stephen
  • 5,362
  • 1
  • 22
  • 33