Adding new methods to existing classes

Discussion in 'Javascript' started by Phat G5 (G3), Aug 27, 2007.

  1. Phat G5 (G3)

    Phat G5 (G3) Guest

    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
    Phat G5 (G3), Aug 27, 2007
    #1
    1. Advertising

  2. Phat G5 (G3)

    RobG Guest

    On Aug 27, 1:55 pm, "Phat G5 (G3)" <> wrote:
    > 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 )


    --
    Rob
    RobG, Aug 27, 2007
    #2
    1. Advertising

  3. Phat G5 (G3)

    Phat G5 (G3) Guest

    in article , RobG at
    wrote on 8/27/07 1:52 AM:

    > On Aug 27, 1:55 pm, "Phat G5 (G3)" <> wrote:
    >> 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 )
    >
    >
    > --
    > 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 )
    return( true )
    return( false );
    };

    var groups = new Array(0);
    var dials = x.form.getElementsByTagName("input")
    for( var i in dials )
    if( dials.type == "radio" && !groups.find(dials.name) )
    groups = groups.concat(new Array(dials.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][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
    Phat G5 (G3), Aug 27, 2007
    #3
  4. On Aug 27, 6:45 am, "Phat G5 (G3)" <> wrote:
    > 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 == 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/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
    }
    }

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

    -David
    David Golightly, Aug 28, 2007
    #4
  5. Phat G5 (G3)

    Phat G5 (G3) Guest

    in article , David
    Golightly at wrote on 8/27/07 6:23 PM:

    > On Aug 27, 6:45 am, "Phat G5 (G3)" <> wrote:
    >> 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 == 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/Core_JavaScript_1.5_Reference: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.type == "radio" && !groups.find(dials.name) )
    > groups = groups.concat(new Array(dials.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][j].checked.



    Not sure. Could you please elaborate?


    Thanks again,

    -S
    Phat G5 (G3), Aug 28, 2007
    #5
  6. Phat G5 (G3)

    Phat G5 (G3) Guest

    in article , David
    Golightly at wrote on 8/27/07 6:23 PM:

    > On Aug 27, 6:45 am, "Phat G5 (G3)" <> wrote:
    >> 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 == 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/Core_JavaScript_1.5_Reference: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.type == "radio" && !groups.find(dials.name) )
    groups = groups.concat([dials.name]);

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


    Thanks

    -S
    Phat G5 (G3), Aug 28, 2007
    #6
  7. David Golightly wrote:
    > On Aug 27, 6:45 am, "Phat G5 (G3)" <> wrote:
    >> 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
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
    Thomas 'PointedEars' Lahn, Aug 28, 2007
    #7
  8. On Aug 28, 1:56 am, Thomas 'PointedEars' Lahn wrote:
    > David Golightly wrote:
    > > 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.


    As always, I can learn from your dogmatic advice. Though in this case
    it's baseless; it's folly to even start to think about supporting
    browsers made (and abandoned by their makers) before 1999, unless you
    have very specific reasons for doing so. Preferring [] to - new
    Array(0) - is recommended by the standardistas I care about, such as
    Brendan Eich and Douglas Crockford, so I'll ignore your suggestion
    here.

    > > 2. Never, ever use the for .. in syntax to iterate through an Array,
    > > *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.


    The reasoning is hardly flawed. Unless you really know what you're
    doing, you don't have much reason to do either thing. So this is a
    fine rule of thumb. Care to give an example of what you're talking
    about here?

    >
    > > 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.


    Perhaps. Could you explain?

    >
    > > 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.


    Nope again. A paren *might* be advisable to wrap a long expression,
    but should not be used automatically with - return - as though it were
    a function. See Crockford (ibid.) for justification.

    > > 4. Always end lines in semicolons.

    >
    > That ignores that a line does not need to end a statement, which turns it
    > into bad advice.


    Nitpicking. Too often semicolons are left off where they're later
    inserted by the compiler, which leads to bugs.

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

    >
    > For you as well.


    Hm, I don't see that my code produces any errors in JSLint. Give an
    example. Also, JSLint exists to *enlighten*, not to enforce.

    > > 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. And it's better to start with something that's at least
    *partially* compatible with *some* browsers than invent your own
    solution that's not compatible with *any* browser.

    -David
    David Golightly, Aug 28, 2007
    #8
  9. David Golightly wrote:
    > On Aug 28, 1:56 am, Thomas 'PointedEars' Lahn wrote:
    >> David Golightly wrote:
    >>> 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.

    >
    > As always, I can learn from your dogmatic advice.


    It is not dogmatic, it merely points out the flaws in your "argumentation".

    BTW: It was you you who started giving dogmatic advice by recommending that
    the Array constructor should not be used, without providing a reason for
    that recommendation.

    > Though in this case it's baseless; it's folly to even start to think about
    > supporting browsers made (and abandoned by their makers) before 1999, unless
    > you have very specific reasons for doing so.


    The very specific reason is backwards compatibility.

    > Preferring [] to - new Array(0) -


    As I said, those two are *not* semantically identical.

    > is recommended by the standardistas I care about, such as Brendan Eich and
    > Douglas Crockford, so I'll ignore your suggestion here.


    Logical fallacy: ipse dixit. <http://en.wikipedia.org/wiki/Appeal_to_authority>

    See below.

    >>> 2. Never, ever use the for .. in syntax to iterate through an Array,
    >>> *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.

    >
    > The reasoning is hardly flawed.


    Yes, it is. It is implying that iterating through an array always has to
    follow an order; it is also saying that for...in should not be used on Array
    objects (no matter the reason), and it is implying that a valid reason for
    not using for...in on Array objects is that their prototype object may be
    augmented.

    > Unless you really know what you're doing, you don't have much reason to do
    > either thing.


    If you do not really know what you are doing, you should not do anything
    because the results would be ultimately fatal otherwise.

    > So this is a fine rule of thumb. Care to give an example of what you're talking
    > about here?


    /**
    * @see http://PointedEars.de/scripts/types.js
    */
    function isMethodType(s)
    {
    return /\b(function|object)\b/i.test(s);
    }

    Array.prototype.forEach = function(callback)
    {
    if (isMethodType(typeof callback) && callback)
    {
    var h = isMethodType(typeof this.hasOwnProperty)
    && this.hasOwnProperty;
    for (var i in this)
    {
    if ((h && this.hasOwnProperty(i))

    // or implement a search for previously
    // registered property names here
    || (!h && i != "forEach"))
    {
    callback(i, this);
    }
    }
    }
    };

    >>> 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.

    >
    > Perhaps. Could you explain?


    0 evaluates to `false', anything else evaluates to `true'.

    >>> 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.

    >
    > Nope again. A paren *might* be advisable to wrap a long expression,
    > but should not be used automatically with - return - as though it were
    > a function.


    Whitespace between keyword and value suffices for the keyword not to be
    misinterpreted by the human reader as a function/method. It is merely a
    matter of code style.

    > See Crockford (ibid.) for justification.


    Same fallacy here.

    >>> 4. Always end lines in semicolons.

    >> That ignores that a line does not need to end a statement, which turns it
    >> into bad advice.

    >
    > Nitpicking. Too often semicolons are left off where they're later
    > inserted by the compiler, which leads to bugs.


    I did not debate that.

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

    >> For you as well.

    >
    > Hm, I don't see that my code produces any errors in JSLint. Give an
    > example. Also, JSLint exists to *enlighten*, not to enforce.


    Enlightenment is man's leaving his self-caused immaturity. Immaturity is
    the incapacity to use one's intelligence without the guidance of another.
    -- Immanuel Kant, "What is Enlightenment?" (1784)

    >>> 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.


    At least
    http://developer.kde.org/documentation/library/3.4-api/kjs/html/array__object_8cpp-source.html
    contains nothing of the kind.

    > And it's better to start with something that's at least
    > *partially* compatible with *some* browsers than invent your own
    > solution that's not compatible with *any* browser.


    Flawed reasoning again. Any own (user-defined) solution would have to
    be compatible with any browser, or it does not deserve its designation.


    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, <f806at$ail$1$>
    Thomas 'PointedEars' Lahn, Aug 28, 2007
    #9
  10. 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.

    >
    > At least
    > http://developer.kde.org/documentation/library/3.4-api/kjs/html/array__object_8cpp-source.html
    > contains nothing of the kind.


    And neither does

    http://developer.kde.org/documentat...idocs/kjs/html/array__object_8cpp-source.html

    which would apply to Konqueror 3.5.x.

    It should also be noted that Konqueror is *not* based on Apple WebKit;
    it uses KHTML. Konqueror's ECMAScript implementation is KJS.

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

    http://trac.webkit.org/projects/web... 2007-007/JavaScriptCore/kjs/array_object.cpp

    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.


    PointedEars
    --
    Anyone who slaps a 'this page is best viewed with Browser X' label on
    a Web page appears to be yearning for the bad old days, before the Web,
    when you had very little chance of reading a document written on another
    computer, another word processor, or another network. -- Tim Berners-Lee
    Thomas 'PointedEars' Lahn, Aug 28, 2007
    #10
  11. On Aug 28, 10:09 am, Thomas 'PointedEars' Lahn <>
    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/webkit/browser/releases/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
    David Golightly, Aug 28, 2007
    #11
  12. 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, <f806at$ail$1$>
    Thomas 'PointedEars' Lahn, Aug 28, 2007
    #12
  13. On Aug 27, 10:51 pm, "Phat G5 (G3)" <> wrote:
    > var groups = [];
    > var dials = x.form.getElementsByTagName("input")
    > for( var i =0; i<dials.length; i++ )
    > if( dials.type == "radio" && !groups.find(dials.name) )
    > groups = groups.concat([dials.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
    David Golightly, Aug 28, 2007
    #13
  14. 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?

    > and Webkit/Safari),


    That remains to be proved.

    > [it] will perform much better than any other "find"
    > solution implemented in native JS.


    Of course.

    > Its use is also consistent with String.prototype.indexOf, which is
    > implemented in JS 1.0.


    You are comparing apples and oranges.


    PointedEars
    --
    Anyone who slaps a 'this page is best viewed with Browser X' label on
    a Web page appears to be yearning for the bad old days, before the Web,
    when you had very little chance of reading a document written on another
    computer, another word processor, or another network. -- Tim Berners-Lee
    Thomas 'PointedEars' Lahn, Aug 28, 2007
    #14
  15. David Golightly wrote:
    > On Aug 27, 10:51 pm, "Phat G5 (G3)" <> wrote:
    >> var groups = [];
    >> var dials = x.form.getElementsByTagName("input")
    >> for( var i =0; i<dials.length; i++ )
    >> if( dials.type == "radio" && !groups.find(dials.name) )
    >> groups = groups.concat([dials.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');


    Missing feature test, needless dependency on DOM Level 1+ Core methods.

    > // 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++]) {


    With i iterations, this will yield a warning for i+1 iterations,
    and rightly so.

    > if (dial.type == 'radio' && (groups.indexOf(dial.name) == -1)) {
    > groups[groups.length] = dial.name;


    One who dares to use Array.prototype.indexOf() should not be afraid to use
    Array.prototype.push().

    > }
    > }


    That code does not qualify as "better/more efficient and less code dependent".

    var groups = new Array();
    var dials = x.form.elements, dial;

    // can be further optimized if reverse order is OK
    for (var i = 0, len = dials.length; i < len; i++)
    {
    var dial = dials;

    if (/input/i.test(dial.tagName)
    && /radio/i.test(dial.type)
    && groups.indexOf(dial.name) < 0)
    {
    groups.push(dial.name);
    }
    }


    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, <f806at$ail$1$>
    Thomas 'PointedEars' Lahn, Aug 28, 2007
    #15
  16. On Aug 28, 10:33 am, Thomas 'PointedEars' Lahn <>
    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
    David Golightly, Aug 28, 2007
    #16
  17. David Golightly wrote:
    > [...] Thomas 'PointedEars' Lahn [...] 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.


    Thanks for a good laugh.

    >>> 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.


    If you observe more closely, I looked at the most recent code which however
    was merged on 2005-07-27 (as the document you referred to also shows.)
    I searched array_object.cpp for occurrences of "indexof" (case-insensitive),
    especially as `case' in ArrayProtoFuncImp::call. I just did not expect it
    to be defined through ArrayProtoFunc::callAsFunction. As C++ is obviously
    not my specialty, maybe you can point out how it was implemented in the code
    I referred to before.

    > 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. [...]


    (Watch my headers.) Did it occur to you that I have no Mac within my
    immediate reach? Have you noticed me writing in another followup that
    I would test this *later*?


    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
    Thomas 'PointedEars' Lahn, Aug 28, 2007
    #17
  18. Thomas 'PointedEars' Lahn wrote:
    > David Golightly wrote:
    >> [...] Thomas 'PointedEars' Lahn [...] wrote:
    >>>> [Array.prototype.indexOf() is provided by] 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.

    >
    > If you observe more closely, I looked at the most recent code which however
    > was merged on 2005-07-27 (as the document you referred to also shows.)
    > I searched array_object.cpp for occurrences of "indexof" (case-insensitive),
    > especially as `case' in ArrayProtoFuncImp::call. I just did not expect it
    > to be defined through ArrayProtoFunc::callAsFunction. As C++ is obviously
    > not my specialty, maybe you can point out how it was implemented in the code
    > I referred to before.


    Ignore that. You have pointed to the *trunk* ChangeLog, where there is a
    `case' for "IndexOf":

    http://trac.webkit.org/projects/web...criptCore/kjs/array_object.cpp?rev=11659#L815

    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.


    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
    Thomas 'PointedEars' Lahn, Aug 28, 2007
    #18
  19. 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/webkit/browser/trunk/JavaScriptCore/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/proposals/bug_fixes.html).

    -David
    David Golightly, Aug 28, 2007
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Amil
    Replies:
    0
    Views:
    367
  2. David Lozzi
    Replies:
    3
    Views:
    1,570
    David Lozzi
    May 18, 2005
  3. Replies:
    0
    Views:
    318
  4. Max Derkachev
    Replies:
    4
    Views:
    660
    Jack Diederich
    May 5, 2005
  5. Spencer Pearson

    Adding an interface to existing classes

    Spencer Pearson, Dec 22, 2011, in forum: Python
    Replies:
    14
    Views:
    315
    Spencer Pearson
    Jan 5, 2012
Loading...

Share This Page