By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,836 Members | 1,840 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,836 IT Pros & Developers. It's quick & easy.

Adding new methods to existing classes

P: n/a
I was toying around with adding a new method to the Array class. It works
fine in FF but not in Safari. I have no idea in IE. I have not gotten that
far yet.

Array.prototype.find = function(item) { for(var i in this )
if( item == this(i) )
return( true )
return( false );
};

Any suggestions?

Thanks, S

Aug 27 '07 #1
Share this Question
Share on Google+
10 Replies


P: n/a
On Aug 27, 1:55 pm, "Phat G5 (G3)" <nob...@noone.comwrote:
I was toying around with adding a new method to the Array class. It works
fine in FF but not in Safari. I have no idea in IE. I have not gotten that
far yet.

Array.prototype.find = function(item) { for(var i in this )
if( item == this(i)
Don't forget to manually wrap your code at about 70 characters to
allow for auto-wrapping.

IE often confuses () with [], maybe you have discovered Firefox trying
to make allowances for that (or not... just a guess).

Try:

if( item == this[i] )
--
Rob

Aug 27 '07 #2

P: n/a
in article 11**********************@r23g2000prd.googlegroups. com, RobG at
rg***@iinet.net.au wrote on 8/27/07 1:52 AM:
On Aug 27, 1:55 pm, "Phat G5 (G3)" <nob...@noone.comwrote:
>I was toying around with adding a new method to the Array class. It works
fine in FF but not in Safari. I have no idea in IE. I have not gotten that
far yet.

Array.prototype.find = function(item) { for(var i in this )
if( item == this(i)

Don't forget to manually wrap your code at about 70 characters to
allow for auto-wrapping.

IE often confuses () with [], maybe you have discovered Firefox trying
to make allowances for that (or not... just a guess).

Try:

if( item == this[i] )
--
Rob
That was a typo I had fixed and forgot to post before sending. Sorry. Here
is a basic idea of what I was doing.

Array.prototype.find = function(item) { for( var i in this )
if( item == this[i] )
return( true )
return( false );
};

var groups = new Array(0);
var dials = x.form.getElementsByTagName("input")
for( var i in dials )
if( dials[i].type == "radio" && !groups.find(dials[i].name) )
groups = groups.concat(new Array(dials[i].name))
I was trying to go thru the radio dials of a form and create an array of
just the radio dial groups/names and then be able to parse the groups one at
a time like theForm.elements[groups[i]][j].checked. Checking the output of
groups yields an empty array. For testing purposes I just took the above
method and did a quick test.

var x = new Array("zz");
alert(x.find("zz")) returns false every time in Safari and IE6+7 but true in
Firefox.
It would appear the prototype registers but it's not recognizing it's own
attributes and never iterates thru them and ultimately hits return false.
Changing from a for..in loop to a regular for loop makes no difference. Any
other suggestions?

Thanks

-S

Aug 27 '07 #3

P: n/a
On Aug 27, 6:45 am, "Phat G5 (G3)" <nob...@noone.comwrote:
var x = new Array("zz");
alert(x.find("zz")) returns false every time in Safari and IE6+7 but true in
Firefox.

It would appear the prototype registers but it's not recognizing it's own
attributes and never iterates thru them and ultimately hits return false.
Changing from a for..in loop to a regular for loop makes no difference. Any
other suggestions?
Well, yes:

1. Use [], not the Array constructor.
2. Never, ever use the for .. in syntax to iterate through an Array,
*especially* if you're extending Array.prototype. Use a conventional
for (var i=0, len=this.length; i<len; i++) loop instead.
3. Don't use parentheses with the "return" keyword.
4. Always end lines in semicolons.
5. If you're having trouble with loops and/or if statements, wrap
their blocks in curly braces {}.

Run your code through JSLint (http://www.jslint.com/lint.html) for
some enlightening suggestions.

Thus, your code becomes:

Array.prototype.find = function (item) {
for (var i=0; i<this.length; i++) {
if (this[i] == item) {
return true;
}
}
return false;
};

such that the test ['a', 'b', 'c'].find('b') === true in IE.

But a better technique would be to implement JS 1.6's

if (typeof Array.prototype.indexOf != 'function') {
Array.prototype.indexOf = function (item) {
// .. implementation here
// see http://developer.mozilla.org/en/docs...:Array:indexOf
}
}

as it's already there on most every browser but IE.

-David

Aug 28 '07 #4

P: n/a
in article 11**********************@l22g2000prc.googlegroups. com, David
Golightly at da******@gmail.com wrote on 8/27/07 6:23 PM:
On Aug 27, 6:45 am, "Phat G5 (G3)" <nob...@noone.comwrote:
>var x = new Array("zz");
alert(x.find("zz")) returns false every time in Safari and IE6+7 but true in
Firefox.

It would appear the prototype registers but it's not recognizing it's own
attributes and never iterates thru them and ultimately hits return false.
Changing from a for..in loop to a regular for loop makes no difference. Any
other suggestions?

Well, yes:

1. Use [], not the Array constructor.
2. Never, ever use the for .. in syntax to iterate through an Array,
*especially* if you're extending Array.prototype. Use a conventional
for (var i=0, len=this.length; i<len; i++) loop instead.
3. Don't use parentheses with the "return" keyword.
4. Always end lines in semicolons.
5. If you're having trouble with loops and/or if statements, wrap
their blocks in curly braces {}.

Run your code through JSLint (http://www.jslint.com/lint.html) for
some enlightening suggestions.

Thus, your code becomes:

Array.prototype.find = function (item) {
for (var i=0; i<this.length; i++) {
if (this[i] == item) {
return true;
}
}
return false;
};

such that the test ['a', 'b', 'c'].find('b') === true in IE.

But a better technique would be to implement JS 1.6's

if (typeof Array.prototype.indexOf != 'function') {
Array.prototype.indexOf = function (item) {
// .. implementation here
// see
http://developer.mozilla.org/en/docs...ce:Global_Obje
cts:Array:indexOf
}
}

as it's already there on most every browser but IE.

-David
David,

Thank you for your suggestions... I was unsure what you meant by one of the
things. Item 1 you said :
1. Use [], not the Array constructor.
Was that in relation to the question I had about the following?
var groups = new Array(0);
var dials = x.form.getElementsByTagName("input")
for( var i in dials )
if( dials[i].type == "radio" && !groups.find(dials[i].name) )
groups = groups.concat(new Array(dials[i].name))
I was trying to go thru the radio dials of a form and create an array of
just the radio dial groups/names and then be able to parse the groups one at
a time like theForm.elements[groups[i]][j].checked.

Not sure. Could you please elaborate?
Thanks again,

-S

Aug 28 '07 #5

P: n/a
in article 11**********************@l22g2000prc.googlegroups. com, David
Golightly at da******@gmail.com wrote on 8/27/07 6:23 PM:
On Aug 27, 6:45 am, "Phat G5 (G3)" <nob...@noone.comwrote:
>var x = new Array("zz");
alert(x.find("zz")) returns false every time in Safari and IE6+7 but true in
Firefox.

It would appear the prototype registers but it's not recognizing it's own
attributes and never iterates thru them and ultimately hits return false.
Changing from a for..in loop to a regular for loop makes no difference. Any
other suggestions?

Well, yes:

1. Use [], not the Array constructor.
2. Never, ever use the for .. in syntax to iterate through an Array,
*especially* if you're extending Array.prototype. Use a conventional
for (var i=0, len=this.length; i<len; i++) loop instead.
3. Don't use parentheses with the "return" keyword.
4. Always end lines in semicolons.
5. If you're having trouble with loops and/or if statements, wrap
their blocks in curly braces {}.

Run your code through JSLint (http://www.jslint.com/lint.html) for
some enlightening suggestions.

Thus, your code becomes:

Array.prototype.find = function (item) {
for (var i=0; i<this.length; i++) {
if (this[i] == item) {
return true;
}
}
return false;
};

such that the test ['a', 'b', 'c'].find('b') === true in IE.

But a better technique would be to implement JS 1.6's

if (typeof Array.prototype.indexOf != 'function') {
Array.prototype.indexOf = function (item) {
// .. implementation here
// see
http://developer.mozilla.org/en/docs...ce:Global_Obje
cts:Array:indexOf
}
}

as it's already there on most every browser but IE.

-David
David,

I think I figured out what you meant about option 1. Is this the suggested
change?

var groups = [];
var dials = x.form.getElementsByTagName("input")
for( var i =0; i<dials.length; i++ )
if( dials[i].type == "radio" && !groups.find(dials[i].name) )
groups = groups.concat([dials[i].name]);

It does work... But, is there a better/more efficient and less code
dependent way of doing this?
Thanks

-S


Aug 28 '07 #6

P: n/a
On Aug 28, 10:09 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Thomas 'PointedEars' Lahn wrote:
David Golightly wrote:
On Aug 28, 1:56 am, Thomas 'PointedEars' Lahn wrote:
David Golightly wrote:
But a better technique would be to implement JS 1.6's
[...]
as it's already there on most every browser but IE.
It is implemented since JavaScript 1.6 in Gecko-based UAs, and is not
part of any standard. That is hardly "most every browser but IE".
Not quite. Webkit-based browsers (Safari/Konquereror) implement this
as well.

Apple Safari uses WebKit, which contains WebCore (based on KHTML) and
JavaScriptCore (based on KJS). However,

http://trac.webkit.org/projects/webk.../Apple/Tiger/S...

also does not contain anything that would indicate Safari would support
Array.prototype.indexOf(). I will test that on our Mac later, but I don't
expect to be surprised here.
True, I erroneously extrapolated Webkit == Safari == Konqueror.
However, - typeof [].indexOf - in Safari 2.0.4 (quite old already)
gives "function".

-David

Aug 28 '07 #7

P: n/a
On Aug 27, 10:51 pm, "Phat G5 (G3)" <nob...@noone.comwrote:
var groups = [];
var dials = x.form.getElementsByTagName("input")
for( var i =0; i<dials.length; i++ )
if( dials[i].type == "radio" && !groups.find(dials[i].name) )
groups = groups.concat([dials[i].name]);

It does work... But, is there a better/more efficient and less code
dependent way of doing this?
I would recommend:

var groups = [];
var dial, i=0;
var dials = x.form.getElementsByTagName('input');

// cache the current element in a local variable for quicker lookup
// el.getElementsByTagName will always return a NodeCollection which
// never has empty elements
while (dial=dials[i++]) {
if (dial.type == 'radio' && (groups.indexOf(dial.name) == -1)) {
groups[groups.length] = dial.name;
}
}

On browsers that provide it natively in the JS engine (Gecko/Firefox
and Webkit/Safari), Array.prototype.indexOf will perform much better
than any other "find" solution implemented in native JS. Its use is
also consistent with String.prototype.indexOf, which is implemented in
JS 1.0.

-David

Aug 28 '07 #8

P: n/a
David Golightly wrote:
However, - typeof [].indexOf - in Safari 2.0.4 (quite old already)
It is also known to be quite buggy.
gives "function".
What matters is not what the `typeof' operation yields, but whether the call
is possible (i.e. does not cause a run-time error), and if yes, whether it
returns what it is supposed to. Does it?
PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Aug 28 '07 #9

P: n/a
On Aug 28, 10:33 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
David Golightly wrote:
On browsers that provide [Array.prototype.indexOf] natively in the
JS engine (Gecko/Firefox

Do you realize that Firefox versions before 1.5 are still used?
Some people can invest weeks of time and money into supporting
obsolete (and unsupported) browsers with less than 1% market share.
Others have work to do.
and Webkit/Safari),

That remains to be proved.
No it doesn't: http://trac.webkit.org/projects/webkit/changeset/11659

Not sure why you looked at 2 1/2 year-old code.

Verified (in-browser) that it does indeed work with intended results
in Safari >= 2.0, which you easily could've done, except that instead
you decided to continue fighting. This, unfortunately, is why, in
spite of the truth of half of what you have to say, people will
continue to ignore your points: you insist on being right, even when
you're clearly not. Step back from the need to constantly prove
everyone wrong, and pick your battles more carefully, and you might
begin to have instructive value for the community.
Its use is also consistent with String.prototype.indexOf, which is
implemented in JS 1.0.

You are comparing apples and oranges.
Not exactly. While a JavaScript string, unlike a C string (for
example), is NOT simply an Array of characters, algorithms applied to
each are similar for the simple reason that it makes sense
conceptually to treat them similarly when searching.

-David

Aug 28 '07 #10

P: n/a
On Aug 28, 11:38 am, Thomas 'PointedEars' Lahn wrote:
Ignore that. You have pointed to the *trunk* ChangeLog, where there is a
`case' for "IndexOf":

http://trac.webkit.org/projects/webk...vaScriptCore/k...

If it works in your Safari, then that has to be a trunk version. So
built-in Array.prototype.indexOf() support appears to be nothing that can be
expected for a Safari release. As explained above, I searched the source
for the most recent security update for the Tiger *release* branch, where
that feature is *not* included (unless Apple's does not show actual source
online).

I am quite curious what my tests with "my" Safari version will reveal
(hopefully next week). Be sure I post the result here.
Ok, my bad. My install of Webkit lied to me about the version number;
checking against Safari release (2.0.4) reveals that [].indexOf is
indeed undefined. However, Safari 3 beta *does* support the Array
extras. So you can expect native "array extras" support with the next
(and current Beta) Safari release, but not in current official
releases. And although the addition of the JS 1.6 Array extras was
proposed by Brendan Eich, it's not in the spec for ECMA 4, though
that's still an open question (see http://developer.mozilla.org/es4/pro...ug_fixes.html).

-David

Aug 28 '07 #11

This discussion thread is closed

Replies have been disabled for this discussion.