David said:
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.
Given that the Array initializer `[...]' is not universally supported
(introduced in JavaScript 1.3, JScript 2.0, ECMAScript 3), but Array() can
be considered to be so (introduced in JavaScript 1.1, JScript 1.0,
ECMAScript 1), that is bad advice.
There is nothing wrong with the Array constructor as long as it is watched
for what the first argument is; if it is a number, it is
implementation-dependent whether the first argument denotes the number of
elements that are initialized with `undefined' in the encapsulated array
data structure, or the value of the first and only initialized element of
that array.
2. Never, ever use the for .. in syntax to iterate through an Array,
Depends. When order is not significant, there is nothing wrong in using
for...in, which is supported since the very first implementations.
*especially* if you're extending Array.prototype.
The reasoning is flawed. Because of the issue with the `in' operator, one
should have very good reasons before augmenting the Array.prototype object.
However, the `in' operator can still be used if used within a wrapper
method for the augmented prototype.
Use a conventional for (var i=0, len=this.length; i<len; i++) loop instead.
That is correct when order is significant, however it is less efficient when
it is not. Also, if iteration in reverse order is acceptable,
for (var i = this.length; i--
is more efficient than the above.
3. Don't use parentheses with the "return" keyword.
There is nothing wrong with doing that. And given that some expressions do
not fit on one line if code style is observed, and that automatic semicolon
insertion exists, this is bad advice.
4. Always end lines in semicolons.
That ignores that a line does not need to end a statement, which turns it
into bad advice.
5. If you're having trouble with loops and/or if statements, wrap
their blocks in curly braces {}.
All loop/conditional code blocks that do not fit the loop statement line or
consist of more than one line (code style applied) should be wrapped so.
Run your code through JSLint (
http://www.jslint.com/lint.html) for
some enlightening suggestions.
For you as well.
Thus, your code becomes:
Array.prototype.find = function (item) {
for (var i=0; i<this.length; i++) {
Order is not significant here.
if (this == item) {
return true;
}
}
return false;
};
such that the test ['a', 'b', 'c'].find('b') === true in IE.
That ignores that `==' is a type-converting comparison. Therefore, with
the above code, e.g. [false].find(0) yields true as well, as does
[true].find(1).
Array.prototype.find = function(item)
{
for (var i = this.length; i--
{
if (this === item)
{
return true;
}
}
return false;
};
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".
PointedEars