Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 12-20-2004, 10:44 AM   PM User | #1
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
Why do prototyped methods of Array show up as members in individual arrays?

Here's some code to demonstrate how I came across this problem:
Code:
//prototype a custom method to Array
Array.prototype.something = function()
{

};

//prototype a method which is native 
//to all test browsers except IE5.0
Array.prototype.push = function()
{

};

//data is a non-associative array
var data = [];

//therefore it has no length property
//so to find its length we have to iterate like this
var dataLen = 0;
for(var i in data) { dataLen++; }

//tell us the length of the array
alert(dataLen);
We get 1 in all browsers except for IE5.0, which returns 2. The differences makes sense, because both methods are custom to IE5.0, whereas push() is already native to the others.

The question is - why do prototyped methods show up at all, when native methods do not?
__________________
"Why bother with accessibility? ... Because deep down you know that the web is attractive to people who aren't exactly like you." - Joe Clark

Last edited by brothercake; 12-20-2004 at 10:46 AM..
brothercake is offline   Reply With Quote
Old 12-20-2004, 05:46 PM   PM User | #2
Jeff Mott
Regular Coder

 
Join Date: Sep 2003
Posts: 290
Thanks: 0
Thanked 0 Times in 0 Posts
Jeff Mott is an unknown quantity at this point
Quote:
//data is a non-associative array
//therefore it has no length property
In fact, non-associative arrays do have length. Associative arrays do not.
Jeff Mott is offline   Reply With Quote
Old 12-20-2004, 07:07 PM   PM User | #3
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
My bad - what I mean is, an array which is indexed with string keys
__________________
"Why bother with accessibility? ... Because deep down you know that the web is attractive to people who aren't exactly like you." - Joe Clark
brothercake is offline   Reply With Quote
Old 12-20-2004, 07:36 PM   PM User | #4
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
The reason is that host methods in general are defined to not be enumerable, while all native methods are. That is in effect for the entire prototype chain, not just the object the method is placed upon. The member lookup scheme is indifferent to whether it's looking at direct members of the object or whether it's looking at prototype members. That way there is no need for building separate internal lookup methods for the two cases - there is only one case, in which you search an object for a member and if not finding it starting the same process with the next object in the prototype chain.

Also, all arrays have length, whether you use them as associative arrays or not. It's only objects, which can be used as hashtables/associative arrays if you wish, that do not have a length. Whether you use string keys or not is irrelevant. This can easily be shown by doing the following:
Code:
var
    o=[true];
o['0']=false;
alert(o[0]); // => false
The reason is that all lookups in JavaScript are by string keys, and if you don't use a string it will be converted to a string before doing the lookup.
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 12-21-2004, 10:58 AM   PM User | #5
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
Okay I'll buy that Apart from this:
Quote:
Originally Posted by liorean
Also, all arrays have length, whether you use them as associative arrays or not. .
They don't have a length property ...
Code:
var data = [];
data['foo'] = 'bar';
alert(data.length); //alerts 0
__________________
"Why bother with accessibility? ... Because deep down you know that the web is attractive to people who aren't exactly like you." - Joe Clark
brothercake is offline   Reply With Quote
Old 12-21-2004, 04:15 PM   PM User | #6
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
Quote:
Originally Posted by brothercake
They don't have a length property ...
Perfect example, exactly the opposite conclusion to what I would have drawn from it. If it didn't have a length property it would have returned undefined.
Quote:
Code:
var data = [];
data['foo'] = 'bar';
alert(data.length); //alerts 0
Object properties and array elements are fundamentally different. (Well, not in implementation but in how it looks from an outside perspective.) Adding an object property to an array naturally doesn't increment the length of the array, because you have not added an array element. Array elements are a subset of object properties on Array type objects, namely those object properties that have a numeric index. You cannot access object properties on an array using numeric index, so it makes no sense to add them to the length - that would break any looping through the array if you allowed it. JavaScript doesn't have any native Collection/Dictionary object (which is just that - a hashtable were all hashes are also accessible by numeric index), so if that's the feature you're looking for, you'll have to write the object for it yourself.
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 12-21-2004, 10:59 PM   PM User | #7
brothercake
Senior Coder


 
Join Date: Jun 2002
Location: near Oswestry
Posts: 4,508
Thanks: 0
Thanked 0 Times in 0 Posts
brothercake is an unknown quantity at this point
Gotcha. Now I understand

What I really need is to be able to go "for(i in myarray)" and be confident that prototyped methods of Array which [may] exist in other [unknown] scripting are not included. But I can acheive that by checking each iteration with typeof, or further testing it as necessary, to determine if it's a member I'm interested in.

Thanks for your help, as ever
__________________
"Why bother with accessibility? ... Because deep down you know that the web is attractive to people who aren't exactly like you." - Joe Clark

Last edited by brothercake; 12-21-2004 at 11:08 PM..
brothercake is offline   Reply With Quote
Old 06-07-2006, 11:48 PM   PM User | #8
ca_redwards
Regular Coder

 
Join Date: Dec 2002
Posts: 169
Thanks: 0
Thanked 0 Times in 0 Posts
ca_redwards is an unknown quantity at this point
Thumbs up I check it against nothing... !

For my own convenience, I attached a few functions onto the Object.prototype...
Code:
// convenience functions
Object.prototype.write=function(){document.write(this);return this}
Object.prototype.alert=function(){window.alert(this);return this}
Object.prototype.status=function(){window.status=this;return this}
But then discovered that I couldn't simply walk the attributes of a generic object without bumping into my own function identifiers. To prevent that, I found that if I test a given attribute against an empty object, then I can determine which are pre-existing attributes and which are not...
Code:
$=function(x,json){
	var elem=document.getElementById(x);
	if(json)for(a in json)if(!{}[a])elem[a]=json[a];
	return elem
};
_=function(x,json){
	var elem=document.createElement(x);
	if(json)for(a in json)if(!{}[a])elem[a]=json[a];
	return elem
};
BTW: I use my $ function for manipulation of existing DOM objects and the _ function for creating new DOM objects. By passing a JSON (JavaScript Object Notation) parameter, I can very easily assign attributes and attach event handlers.
Code:
$('someElementID',
	{'color':'red',
	 'onblur':function(){('ERROR: Invalid '+this.id+' value ['+this.value+']').alert();this.focus()}
	}
);

Last edited by ca_redwards; 06-08-2006 at 12:59 AM..
ca_redwards is offline   Reply With Quote
Old 06-07-2006, 11:57 PM   PM User | #9
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
Boy, did you check the age of the thread you ressurected?



Oh, and if I were you I'd change
Code:
if(json)for(a in json)if(!{}[a])elem[a]=json[a];
to
Code:
if(json)for(a in json)if(json.hasOwnProperty(a))elem[a]=json[a];
That way it works for any type of object.
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 06-08-2006, 12:03 AM   PM User | #10
ca_redwards
Regular Coder

 
Join Date: Dec 2002
Posts: 169
Thanks: 0
Thanked 0 Times in 0 Posts
ca_redwards is an unknown quantity at this point
Quote:
Originally Posted by liorean
Boy, did you check the age of the thread you ressurected?



Oh, and if I were you I'd change
Code:
if(json)for(a in json)if(!{}[a])elem[a]=json[a];
to
Code:
if(json)for(a in json)if(json.hasOwnProperty(a))elem[a]=json[a];
That way it works for any type of object.
Do both (IE and FF) support that method?
ca_redwards is offline   Reply With Quote
Old 06-08-2006, 12:48 AM   PM User | #11
liorean
The thread killer


 
Join Date: Feb 2003
Location: Umeå, Sweden
Posts: 5,575
Thanks: 0
Thanked 84 Times in 75 Posts
liorean will become famous soon enoughliorean will become famous soon enough
I'm not sure about ie5.0 or nn4 (haven't got them installed to test it), but I know op/moz/ie6w support it.
__________________
liorean <[lio@wg]>
Articles: RegEx evolt wsabstract , Named Arguments
Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards
liorean is offline   Reply With Quote
Old 06-08-2006, 10:07 AM   PM User | #12
Kor
Red Devil Mod


 
Kor's Avatar
 
Join Date: Apr 2003
Location: Bucharest, ROMANIA
Posts: 8,478
Thanks: 58
Thanked 379 Times in 375 Posts
Kor has a spectacular aura aboutKor has a spectacular aura about
hasOwnProperty() ... geee, I always thought that this method is an IE only, and I was too lazy to check it in other browsers ...

http://msdn2.microsoft.com/en-us/tz3t700w.aspx

Very useful, I would modify some of my codes with it.
__________________
KOR
Offshore programming
-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
Kor is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 07:38 AM.


Advertisement
Log in to turn off these ads.