Its the isArray() function thing again

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Aaron Gray

    Its the isArray() function thing again

    I know this has probably been argued to death, but I am going to raise it
    fresh again, and basically lets have an unofficial 'isArray()' contest that
    we can hopefully put it to rest as best as we can.

    I have found things that work perfectly well as long as you don't try them
    on MSIE, ie adding Object and Array prototype isArray functions, thus :-

    Object.prototyp e.isArray = function() { return false }
    Array.prototype .isArray = function() { return true }

    This falls down on builtin browser types in IE, so is no good.

    The one version that I have seen is :-

    function isArray( a) { return typeof a.push == "function" }

    Prototype for all its "failings" extends object and provides :-

    Object.extend(O bject, {
    isArray: function(object ) {
    return object != null && typeof object == "object" &&
    'splice' in object && 'join' in object;
    }
    });

    So checking of non null and splice and join maybe better than just checking
    for push.

    So something like :-

    function isArray( o) { return o != null && typeof o == "object" &&
    'push' in o }

    But I am not sure when 'in' was actually introduced.

    function isArray( o) { return o != null && typeof o == "object" &&
    typeof o.push == "function" }

    Would probably do best/better. This is what I have settled on for now.

    Then there was the advice to use === rather than ==, but I dont know when
    that was introduced too, or whether it is really necessary as == works just
    as well AFAICS.

    Any critisisms, advances, or advice ?

    Aaron


  • Peter Michaux

    #2
    Re: Its the isArray() function thing again

    On Jul 26, 3:03 pm, "Aaron Gray" <ang.use...@gma il.comwrote:
    I know this has probably been argued to death, but I am going to raise it
    fresh again, and basically lets have an unofficial 'isArray()' contest that
    we can hopefully put it to rest as best as we can.
    In your actual application code, why are you ever having any trouble
    knowing if a variable references an Array or not? If a function's API
    states it should recieve an array argument, then just send it an array
    argument. If it states it should receive a number, don't send it an
    array. Be careful about bringing the baggage of focusing on type
    checking and casting from languages like Java or C++ to your
    JavaScript programming.
    I have found things that work perfectly well as long as you don't try them
    on MSIE, ie adding Object and Array prototype isArray functions, thus :-
    >
    Object.prototyp e.isArray = function() { return false }
    Array.prototype .isArray = function() { return true }
    Augmenting built in prototypes with generic names like "isArray" is
    likely to collide in an envronment where multiple authors are writing
    the JavaScript.



    This falls down on builtin browser types in IE, so is no good.
    >
    The one version that I have seen is :-
    >
    function isArray( a) { return typeof a.push == "function" }
    That is a very wimpy test in general.

    Prototype for all its "failings" extends object and provides :-
    The quotation marks are not necessary.

    Object.extend(O bject, {
    isArray: function(object ) {
    return object != null && typeof object == "object" &&
    'splice' in object && 'join' in object;
    }
    });
    Why they think writing

    Object.isArray

    is any different than

    PrototypeJS.isA rray

    I will never understand.

    So checking of non null and splice and join maybe better than just checking
    for push.
    >
    So something like :-
    >
    function isArray( o) { return o != null && typeof o == "object" &&
    'push' in o }
    >
    But I am not sure when 'in' was actually introduced.
    >
    function isArray( o) { return o != null && typeof o == "object" &&
    typeof o.push == "function" }
    So if I define a new object in JavaScript with a push function it will
    pass your test. That is a very weak test.

    Would probably do best/better. This is what I have settled on for now.
    >
    Then there was the advice to use === rather than ==, but I dont know when
    that was introduced too,


    or whether it is really necessary as == works just
    as well AFAICS.
    They are not the same. == and != do type coercion.



    Any critisisms, advances, or advice ?
    What's wrong with

    if (obj instanceof Array) {
    // do stuff
    }

    The MDN Web Docs site provides information about Open Web technologies including HTML, CSS, and APIs for both Web sites and progressive web apps.


    Peter

    Comment

    • Lasse Reichstein Nielsen

      #3
      Re: Its the isArray() function thing again

      "Aaron Gray" <ang.usenet@gma il.comwrites:
      I know this has probably been argued to death, but I am going to raise it
      fresh again, and basically lets have an unofficial 'isArray()' contest that
      we can hopefully put it to rest as best as we can.
      Is there a setting where

      obj instanceof Array

      fails to detect an Array?

      ....
      Prototype for all its "failings" extends object
      That's one failing right there :)
      I thought they stopped doing that in later versions?
      and provides :-
      >
      Object.extend(O bject, {
      isArray: function(object ) {
      return object != null && typeof object == "object" &&
      'splice' in object && 'join' in object;
      Sigh. Feature detection is good for detecting features. This is detection
      by inference. This is as bad as
      var isIE = document.all ? 1 : 0;
      (ok, slightly better, the isIE example has more bad points than it has
      keywords)
      So checking of non null and splice and join maybe better than just checking
      for push.
      "maybe" is the operative word. I.e., it's shooting blind and hoping to
      be lucky.
      So something like :-
      >
      function isArray( o) { return o != null && typeof o == "object" &&
      'push' in o }
      >
      But I am not sure when 'in' was actually introduced.
      JScript 5.6
      JavaScript 1.4

      Same versions as "instanceof ", btw.
      function isArray( o) { return o != null && typeof o == "object" &&
      typeof o.push == "function" }
      >
      Would probably do best/better. This is what I have settled on for now.
      And when we implement a stack:

      function Stack() {}
      Stack.prototype .push = function(o) {
      this.head = {elem: o, next: this.head }
      };
      Stack.prototype .pop = function() {
      var head = this.head;
      if (head) {
      var elem = head.elem;
      this.head = head.next;
      return elem;
      }
      };

      it suddently qualifies as an array?

      An object is an Array if it inherits Array.prototype . That's the
      prototype based definition of inheritance.
      Then there was the advice to use === rather than ==, but I dont know when
      that was introduced too, or whether it is really necessary as == works just
      as well AFAICS.
      It's the same when dealing with objects. The "==" operator performs
      type conversion in some cases, whereas the "===" requires both
      operands to have the same type. When the operands are objects, they
      work exactly the same,
      Any critisisms, advances, or advice ?
      What problem are you trying to solve?
      Why?


      In any case, don't try to be clever. Either use "instanceof ", or, if
      it's *really* necessary to support ancient browsers, test simple
      things:

      function isArray(o) {
      return o && o.constructor == Array;
      }

      It's easy to cheat, but anybody actively trying to cheat is going to
      succeede anyway.

      /L
      --
      Lasse Reichstein Nielsen
      DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
      'Faith without judgement merely degrades the spirit divine.'

      Comment

      • Gregor Kofler

        #4
        Re: Its the isArray() function thing again

        Aaron Gray meinte:
        But I am not sure when 'in' was actually introduced.
        Then there was the advice to use === rather than ==, but I dont know when
        that was introduced too
        Before he does it:


        Gregor


        --
        http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
        http://web.gregorkofler.com ::: meine JS-Spielwiese
        http://www.image2d.com ::: Bildagentur für den alpinen Raum

        Comment

        • Gregor Kofler

          #5
          Re: Its the isArray() function thing again

          Aaron Gray meinte:
          I know this has probably been argued to death, but I am going to raise it
          fresh again, and basically lets have an unofficial 'isArray()' contest that
          we can hopefully put it to rest as best as we can.
          Crockford suggests

          var is_array = function(v) {
          return v && typeof v === "object" && v.constructor === Array;
          }

          (wont work on arrays in other windows/frames)

          or

          var is_array = function(v) {
          return v && typeof v === "object" && typeof v.length === "number" &&
          typeof v.splice === "function" && !(v.propertyIsE numerable("leng th"));
          }

          (I suppose he took splice() because it's a relatively "rare" method)

          Gregor


          --
          http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
          http://web.gregorkofler.com ::: meine JS-Spielwiese
          http://www.image2d.com ::: Bildagentur für den alpinen Raum

          Comment

          • Aaron Gray

            #6
            Re: Its the isArray() function thing again

            "Lasse Reichstein Nielsen" <lrn@hotpop.com wrote in message
            news:4p6cl1cc.f sf@hotpop.com.. .
            "Aaron Gray" <ang.usenet@gma il.comwrites:
            >
            >I know this has probably been argued to death, but I am going to raise it
            >fresh again, and basically lets have an unofficial 'isArray()' contest
            >that
            >we can hopefully put it to rest as best as we can.
            >
            Is there a setting where
            >
            obj instanceof Array
            >
            fails to detect an Array?
            Don't know. But I had forgotten about 'instanceof Array' and thats exactly
            what I need for this specific problem.

            I think people use the other 'weaker' methods to allow inclusion of array
            like objects as well as Arrays.
            In any case, don't try to be clever. Either use "instanceof ", or, if
            it's *really* necessary to support ancient browsers, test simple
            things:
            >
            function isArray(o) {
            return o && o.constructor == Array;
            }
            Thomas is right, I really should read ECMA-262 properly.

            Many thanks,

            Aaron

            Comment

            • dhtml

              #7
              Re: Its the isArray() function thing again

              On Jul 26, 3:36 pm, Lasse Reichstein Nielsen <l...@hotpop.co mwrote:
              "Aaron Gray" <ang.use...@gma il.comwrites:
              I know this has probably been argued to death, but I am going to raise it
              fresh again, and basically lets have an unofficial 'isArray()' contest that
              we can hopefully put it to rest as best as we can.
              >
              Is there a setting where
              >
                obj instanceof Array
              >
              fails to detect an Array?
              There is: When obj is an Array in a different frame than the Array
              constructor, it would be constructed via a different Array
              constructor, and so obj instanceof Array would have to be false.
              otherFrame.obj instanceof otherFrame.Arra y would be true, though.

              Prototype for all its "failings" extends object
              That was quite a long time ago.
              That's one failing right there :)
              I thought they stopped doing that in later versions?
              Yes, they did.

              Garrett

              /L

              Comment

              • Peter Michaux

                #8
                Re: Its the isArray() function thing again

                On Jul 26, 4:52 pm, dhtml <dhtmlkitc...@g mail.comwrote:
                "Aaron Gray" <ang.use...@gma il.comwrites:
                Prototype for all its "failings" extends object
                >
                That was quite a long time ago.
                They are still extending "Object" unnecessarily with function-valued
                properties that could be added to any object. Adding them to "Object"
                is just confusing, in my opinion. They also choose very generic names
                in shared namespaces which is another problem of theirs.



                Peter

                Comment

                • RobG

                  #9
                  Re: Its the isArray() function thing again

                  On Jul 27, 9:52 am, dhtml <dhtmlkitc...@g mail.comwrote:
                  On Jul 26, 3:36 pm, Lasse Reichstein Nielsen <l...@hotpop.co mwrote:
                  >
                  "Aaron Gray" <ang.use...@gma il.comwrites:
                  I know this has probably been argued to death, but I am going to raise it
                  fresh again, and basically lets have an unofficial 'isArray()' contest that
                  we can hopefully put it to rest as best as we can.
                  >
                  Is there a setting where
                  >
                    obj instanceof Array
                  >
                  fails to detect an Array?
                  >
                  There is: When obj is an Array in a different frame than the Array
                  constructor, it would be constructed via a different Array
                  constructor, and so obj instanceof Array would have to be false.
                  otherFrame.obj instanceof otherFrame.Arra y would be true, though.
                  >
                  Prototype for all its "failings" extends object
                  >
                  That was quite a long time ago.
                  >
                  That's one failing right there :)
                  I thought they stopped doing that in later versions?
                  >
                  Yes, they did.
                  They stopped extending Object.prototyp e.

                  --
                  Rob

                  Comment

                  • dhtml

                    #10
                    Re: Its the isArray() function thing again

                    On Jul 26, 7:10 pm, RobG <rg...@iinet.ne t.auwrote:
                    On Jul 27, 9:52 am, dhtml <dhtmlkitc...@g mail.comwrote:
                    >
                    >
                    >
                    On Jul 26, 3:36 pm, Lasse Reichstein Nielsen <l...@hotpop.co mwrote:
                    >
                    "Aaron Gray" <ang.use...@gma il.comwrites:
                    I know this has probably been argued to death, but I am going to raise it
                    fresh again, and basically lets have an unofficial 'isArray()' contest that
                    we can hopefully put it to rest as best as we can.
                    >
                    Is there a setting where
                    >
                      obj instanceof Array
                    >
                    fails to detect an Array?
                    >
                    There is: When obj is an Array in a different frame than the Array
                    constructor, it would be constructed via a different Array
                    constructor, and so obj instanceof Array would have to be false.
                    otherFrame.obj instanceof otherFrame.Arra y would be true, though.
                    >
                    Prototype for all its "failings" extends object
                    >
                    That was quite a long time ago.
                    >
                    That's one failing right there :)
                    I thought they stopped doing that in later versions?
                    >
                    Yes, they did.
                    >
                    They stopped extending Object.prototyp e.
                    >
                    Ah, right that's what I was thinking about. Modifying
                    Object.prototyp e. That was very bad.

                    They still extend Object, which is not as bad. They add a clone()
                    method to Object, and clone is an ES3.1 Proposal. I asked Allen about
                    that

                    Object.clone is proposed for ES 3.1. I did mention it on the list, but
                    Allen was replying to a lot of responders, so he probably missed what
                    I wrote:

                    | It seems like Object.clone might create compatibility with existing
                    | code. There is already a widespread use of an Object.clone on the
                    web.


                    Garrett
                    --
                    Rob

                    Comment

                    • Peter Michaux

                      #11
                      Re: Its the isArray() function thing again

                      "dhtml" wrote:

                      [snip]
                      "Aaron Gray" wrote:
                      [snip]
                      Prototype for all its "failings" extends object
                      [snip]
                      They still extend Object, which is not as bad. They add a clone()
                      method to Object, and clone is an ES3.1 Proposal. I asked Allen about
                      that
                      >
                      Object.clone is proposed for ES 3.1. I did mention it on the list, but
                      Allen was replying to a lot of responders, so he probably missed what
                      Who is "Allen"?
                      I wrote:
                      >
                      | It seems like Object.clone might create compatibility with existing
                      | code. There is already a widespread use of an Object.clone on the
                      web.
                      "compatibil ity" or "incompatibilit y" with Prototype.js' Object.clone?
                      It looks to me like there will be incompatibility as Prototype.js'
                      Object.clone is a shallow copy and the ES3.1 Object.clone is a much
                      deeper clone of an Object. This is why adding generically named
                      properties in shared namespaces is a problem. The Prototype.js
                      developers have been burned by this at least a few times in the past
                      two years. That may imply they have influence over the evolution of
                      JavaScript and the DOM. Unfortunately it also means they are causing
                      unnecessary maintenance headaches for Prototype.js users.

                      Peter

                      Comment

                      • Jorge

                        #12
                        Re: Its the isArray() function thing again

                        On Jul 27, 5:55 pm, Peter Michaux <petermich...@g mail.comwrote:
                        >
                        Object.clone is proposed for ES 3.1. I did mention it on the list, but
                        Allen was replying to a lot of responders, so he probably missed what
                        I wrote.
                        >
                        Who is "Allen"?
                        >
                        Allen Wirfs-Brock, http://preview.tinyurl.com/5hf4na

                        --Jorge.

                        Comment

                        • Jorge

                          #13
                          Re: Its the isArray() function thing again

                          On Jul 27, 7:02 pm, Jorge <jo...@jorgecha morro.comwrote:
                          On Jul 27, 5:55 pm, Peter Michaux <petermich...@g mail.comwrote:
                          >
                          >
                          >
                          Object.clone is proposed for ES 3.1. I did mention it on the list, but
                          Allen was replying to a lot of responders, so he probably missed what
                          I wrote.
                          >
                          Who is "Allen"?
                          >
                          Allen Wirfs-Brock,http://preview.tinyurl.com/5hf4na
                          >



                          --Jorge.

                          Comment

                          • Richard Cornford

                            #14
                            Re: Its the isArray() function thing again

                            Jorge wrote:
                            On Jul 27, 5:55 pm, Peter Michaux wrote:
                            >
                            Object.clone is proposed for ES 3.1. I did mention it on the list,
                            but
                            Allen was replying to a lot of responders, so he probably missed
                            what
                            I wrote.
                            >
                            Who is "Allen"?
                            >
                            Allen Wirfs-Brock, http://preview.tinyurl.com/5hf4na

                            There is little point in posting tinyurl URLs as nobody in their right
                            mind would follow one, just as nobody in their right mind would follow a
                            URL found in a spam post.

                            Richard.

                            Comment

                            • Jorge

                              #15
                              Re: Its the isArray() function thing again

                              On Jul 27, 11:53 pm, "Richard Cornford" <Rich...@litote s.demon.co.uk>
                              wrote:
                              >
                              Allen Wirfs-Brock,http://preview.tinyurl.com/5hf4na
                              >
                              There is little point in posting tinyurl URLs as nobody in their right
                              mind would follow one, just as nobody in their right mind would follow a
                              URL found in a spam post.
                              >
                              Not even if it points to a preview, like that one ?
                              We Mac users aren't so frightened of urls.

                              --Jorge.

                              Comment

                              Working...