Array constructor or literal

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dan Rumney

    Array constructor or literal

    I've been taking a look at Douglas Crockford's JSLint.

    One of the conventions that it expects is that arrays be created using
    literal notation
    var arr1 = [];

    as opposed to using a constructor
    var arr2 = new Array();

    I've been a-googling, but the best reason for this that I can find is
    "because it's not necessary to use a constructor".

    I'm wondering:

    1) Is there a way to tell the difference between arr1 and arr2 as
    defined above, once they've been defined?

    2) Is there anything, beyond stylstic reasons, to prefer one method over
    another?


    I've no problem against JSLint choosing a specific convention and
    applying it. I'm just wondering if there is anything *beyond* convention
    to speak in favour of literal over constructor notation.
  • Joost Diepenmaat

    #2
    Re: Array constructor or literal

    Dan Rumney <danrumney@warp mail.netwrites:
    I've been taking a look at Douglas Crockford's JSLint.
    >
    One of the conventions that it expects is that arrays be created using
    literal notation
    var arr1 = [];
    >
    as opposed to using a constructor
    var arr2 = new Array();
    >
    I've been a-googling, but the best reason for this that I can find is
    "because it's not necessary to use a constructor".
    >
    I'm wondering:
    >
    1) Is there a way to tell the difference between arr1 and arr2 as
    defined above, once they've been defined?
    No, unless you override the default Array constructor, which you
    probably shouldn't.

    Tthe "Compatibil ity Between ES3 and Proposed ES4" document discusses
    some of this, see section 1.4 of:


    2) Is there anything, beyond stylstic reasons, to prefer one method
    over another?
    Style is important :-) What would you rather see:

    var aoo = new Array( new Array(),
    new Array( 1, 2, new Array() ) );

    Or

    var aoo = [ [],
    [ 1, 2, [] ] ];

    I definitely prefer the second. Array literals remove a lot of clutter
    from the code. And if you look at object literals vs new Object() the
    difference is even bigger.

    --
    Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/

    Comment

    • Henry

      #3
      Re: Array constructor or literal

      On Jun 12, 2:48 pm, Dan Rumney wrote:
      I've been taking a look at Douglas Crockford's JSLint.
      >
      One of the conventions that it expects is that arrays be
      created using literal notation
      var arr1 = [];
      >
      as opposed to using a constructor
      var arr2 = new Array();
      >
      I've been a-googling, but the best reason for this that I can
      find is "because it's not necessary to use a constructor".
      >
      I'm wondering:
      >
      1) Is there a way to tell the difference between arr1 and
      arr2 as defined above, once they've been defined?
      None.
      2) Is there anything, beyond stylstic reasons, to prefer one
      method over another?
      One is shorter than the other, while neither are unclear.
      I've no problem against JSLint choosing a specific convention
      and applying it. I'm just wondering if there is anything
      *beyond* convention to speak in favour of literal over
      constructor notation.
      One is shorter than the other, while neither are unclear. That is
      probably all.

      Comment

      • Duncan Booth

        #4
        Re: Array constructor or literal

        Dan Rumney <danrumney@warp mail.netwrote:
        I've no problem against JSLint choosing a specific convention and
        applying it. I'm just wondering if there is anything *beyond* convention
        to speak in favour of literal over constructor notation.
        >
        I don't have a problem with this particular convention. The only time I can
        think where it would be important to use the Array constructor explicitly
        would be if you had a function which created an object and the type of the
        object varied somehow. In that case though you'ld be calling 'new theType
        ()' rather than 'new Array()' so jslint wouldn't flag it anyway, and I
        can't think of a concrete example where you'ld do that.

        I do have issues with some of the other warnings generated by jslint which
        is why I produced a modified version that lets you ignore particular error
        messages if you don't like them.

        My modified jslint is at:
        http://codespeak.net/svn/kupu/trunk/kupu/jslint.js if you are interested.
        The same version works with either Rhino or Microsoft's scripting engine.

        Also in the same subversion folder lint.py is a frontend to run jslint over
        a lot of javascript files, every time they've changed (you can't use make
        because there's no output file) and jslint.opts is the set of command line
        options I use for that particular project. I suppressed things like
        'Indentifier already declared' and 'Unnecessary semicolon' because I happen
        to prefer to always prefix my loop variables with 'var', and I also prefer
        to not have to look back through maybe hundreds of lines of code to
        determine when a semi-colon is not required.

        --
        Duncan Booth http://kupuguy.blogspot.com

        Comment

        • Stevo

          #5
          Re: Array constructor or literal

          Duncan Booth wrote:
          Dan Rumney <danrumney@warp mail.netwrote:
          >
          >I've no problem against JSLint choosing a specific convention and
          >applying it. I'm just wondering if there is anything *beyond* convention
          >to speak in favour of literal over constructor notation.
          >>
          I do have issues with some of the other warnings generated by jslint which
          is why I produced a modified version that lets you ignore particular error
          messages if you don't like them.
          I think it's wrong for it to be called jslint when really it should be
          called jscrockford. It's something that he wrote that highlights
          anything that doesn't meet his particular coding standards. They're not
          rules, just preferred styles. Not that I'm saying there's anything wrong
          with the things it complains about, but they're certainly not all
          errors. I tried it once and didn't want to change my code in the way
          necessary to make it happy.

          As I recall from my C days, lint was more like a pre-compiler that would
          tell you what real errors/warnings you have in your code, rather than
          how it's not suiting one person's style choices. It was used because it
          was quicker than running the full compiler.

          Comment

          • VK

            #6
            Re: Array constructor or literal

            On Jun 12, 7:35 pm, Stevo <n...@mail.inva lidwrote:
            I think it's wrong for it to be called jslint when really it should be
            called jscrockford.
            :-) Fully sustained. jslint as it is right now is just like some C
            checker which would mark missing closing brackets - and at the same
            time would issue errors for each opening bracket placed on the same
            line as the method name (or below it). So it is a rather strong
            cocktail of a code checker and a particular pretty-print enforcer.
            Still the author is fairly fair about it:

            "Warning: JSLint will hurt your feelings."
            Moreover no one is forcing to use JSLint as some "final authoritative
            validity" tool. In this aspect W3C HTML Validator is much more
            damaging.

            Concerning the OP's question:
            there is not a damn difference between Array and [] - they are equal.
            One plus of Array is that it allows to set the initial size of the
            array without members' initialization:
            var a = new Array(1000);
            it may be useful if one needs to take extra steps on array elements
            above or below the initial size.

            One plus of [] is that it makes the code uniformly looking with JSON
            data. With Mr. Crockford being the author of JSON, this is - I guess -
            the core of the JSLint's "bracket obsession" :-)

            Comment

            • Stevo

              #7
              Re: Array constructor or literal

              VK wrote:
              On Jun 12, 7:35 pm, Stevo <n...@mail.inva lidwrote:
              >I think it's wrong for it to be called jslint when really it should be
              >called jscrockford.
              >
              :-) Fully sustained. jslint as it is right now is just like some C
              checker which would mark missing closing brackets - and at the same
              time would issue errors for each opening bracket placed on the same
              line as the method name (or below it). So it is a rather strong
              cocktail of a code checker and a particular pretty-print enforcer.
              Still the author is fairly fair about it:

              "Warning: JSLint will hurt your feelings."
              Moreover no one is forcing to use JSLint as some "final authoritative
              validity" tool.
              Absolutely. I hope my message didn't come across excessively negatively
              to JSLint. Didn't meant it to.
              One plus of [] is that it makes the code uniformly looking with JSON
              data. With Mr. Crockford being the author of JSON, this is - I guess -
              the core of the JSLint's "bracket obsession" :-)
              I love the square brackets. I remember the day I did a global replace of
              new Array() with [] and saw the file size reduction :) I'd like to say
              it was 4 years ago I did that, but it was only about 6 months ago ;-)

              Comment

              • Douglas Crockford

                #8
                Re: Array constructor or literal

                Dan Rumney wrote:
                I've been taking a look at Douglas Crockford's JSLint.
                >
                One of the conventions that it expects is that arrays be created using
                literal notation
                var arr1 = [];
                >
                as opposed to using a constructor
                var arr2 = new Array();
                The bracket notation is preferred always. It is smaller and more consistent.

                [] and new Array() do the same thing.

                [1, 2] and new Array(1, 2) do the same thing.

                [1] and new Array(1) do not do the same thing.

                [undefined] and new Array(1) do extremely similar things.

                JSLint, The JavaScript Code Quality and Coverage Tool. This file allows JSLint to be run from a web browser. It can accept a source program and analyze it without sending it over the network.

                Comment

                • Dan Rumney

                  #9
                  Re: Array constructor or literal

                  Douglas Crockford wrote:
                  [snip]
                  >
                  The bracket notation is preferred always. It is smaller and more
                  consistent.
                  >
                  [] and new Array() do the same thing.
                  >
                  [1, 2] and new Array(1, 2) do the same thing.
                  >
                  [1] and new Array(1) do not do the same thing.
                  >
                  [undefined] and new Array(1) do extremely similar things.
                  >
                  http://www.JSLint.com/

                  I'd been wooed by Joost's nested arrays argument, but the example you
                  give here about consistency is the clincher.

                  Personally, I'd be unlikely to mix
                  Array(size)
                  and
                  Array(contents)

                  but I can see that being a general concern. In my opinion, that's a
                  nasty piece of overloading.

                  For what it's worth, I'm not really compelled by arguments of script
                  size. I'm sure there are very *specific* cases where it makes a
                  difference, but we're talking about 9 bytes saved per array creation.
                  At 256kbps, this is only about 280 microseconds per array creation.

                  Still, it's not the function of Usenet to compel me to believe anything.
                  I appreciate JSLint for what it is: a very useful tool to act as a check
                  and balanced against my own coding vagaries... Thanks Douglas!

                  Comment

                  • Thomas 'PointedEars' Lahn

                    #10
                    Re: Array constructor or literal

                    Dan Rumney wrote:
                    I've been taking a look at Douglas Crockford's JSLint.
                    >
                    One of the conventions that it expects is that arrays be created using
                    literal notation
                    var arr1 = [];
                    >
                    as opposed to using a constructor
                    var arr2 = new Array();
                    >
                    I've been a-googling, but the best reason for this that I can find is
                    "because it's not necessary to use a constructor".
                    >
                    I'm wondering:
                    >
                    1) Is there a way to tell the difference between arr1 and arr2 as
                    defined above, once they've been defined?
                    There isn't, both return a reference to an Array object. Array() called as
                    a factory also does:

                    var arr2 = Array(...);

                    (see ES3 Final, 15.4.1)
                    2) Is there anything, beyond stylstic reasons, to prefer one method over
                    another?
                    Inconsistencies in ECMAScript implementations would cause you to prefer the
                    initializer over the constructor/factory call (as Douglas pointed out).

                    Incompatibiliti es between ECMAScript implementations would cause you to
                    prefer the constructor/factory call over the initializer; those are:

                    1. Only JavaScript supports a trailing comma with the initializer.
                    2. The initializer requires JavaScript 1.3, JScript 2.0, or an
                    implementation of ECMAScript Ed. 3. The factory/constructor
                    call only requires JavaScript 1.1, JScript 2.0, or an implementation
                    of ECMAscript Ed. 1.

                    Obviously point 2 is of little importance nowadays. (The next revision of
                    the ECMAScript Support Matrix at <http://PointedEars.de/scripts/es-matrix/>
                    will probably mark this language feature as "safe to use (without feature
                    test)". I have yet to test more implementations to be sure.)

                    I would presume, but I have not tested yet, that there is also a slight
                    performance loss when using the constructor/factory instead of the
                    initializer because of stack operations.


                    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$8 300dec7@news.de mon.co.uk>

                    Comment

                    • Michael Wojcik

                      #11
                      Re: Array constructor or literal

                      Stevo wrote:
                      necessary to make it happy.
                      >
                      As I recall from my C days, lint was more like a pre-compiler that would
                      tell you what real errors/warnings you have in your code, rather than
                      how it's not suiting one person's style choices. It was used because it
                      was quicker than running the full compiler.
                      I fear you misremember. The original lint warned about constructs that
                      were mostly silently accepted by the extant C compilers. Many of these
                      were style issues, such as case-fallthrough.

                      Descendants of that lint, such as Splint, are even more divorced from
                      particular C compilers. They're often C implementations in their own
                      right; they just don't produce a translation. Instead they do things
                      like static data-flow analysis to look for potential use of
                      uninitialized data, orphaned allocated memory, and possibly-unsafe use
                      of standard library functions.

                      Peter van der Linden has a useful discussion of the history and
                      purpose of lint in his _Expert C Programming: Deep C Secrets_.

                      So jslint is pretty squarely in the lint fold. The question is really
                      its author's choices as to what constitutes a "dangerous" or
                      "undesirabl e" construction. On this there will of course be
                      disagreement; but then there is much disagreement over the choices
                      made by the developers of various lints over the years (and similarly
                      for compiler warnings).

                      Since lints traditionally err on the side of false positives, though,
                      it's my opinion that a good lint is a highly configurable lint. It
                      should allow specific warnings, and classes of warnings, to be turned
                      off globally; and it should support source-code annotation to suppress
                      particular warnings for particular segments of code. (The better
                      lints, like Splint, also offer a variety of annotations to give the
                      engine more information about the code.)

                      --
                      Michael Wojcik
                      Micro Focus
                      Rhetoric & Writing, Michigan State University

                      Comment

                      • dhtml

                        #12
                        Re: Array constructor or literal

                        On Jun 12, 2:09 pm, VK <schools_r...@y ahoo.comwrote:
                        On Jun 12, 7:35 pm, Stevo <n...@mail.inva lidwrote:
                        >
                        I think it's wrong for it to be called jslint when really it should be
                        called jscrockford.
                        >
                        I'd like to see JSLint with more options to not warn for some of the
                        things that people find annoying, it could be even more useful for
                        maintaining consistent team code standards, conventions, and
                        formatting (not just the author's coding standards). It would also be
                        useful as an Eclipse plugin.

                        [snip]
                        Concerning the OP's question:
                        there is not a damn difference between Array and [] - they are equal.
                        One plus of Array is that it allows to set the initial size of the
                        array without members' initialization:
                        var a = new Array(1000);
                        it may be useful if one needs to take extra steps on array elements
                        above or below the initial size.
                        >
                        There is a possibility that that aspect could be used to improve
                        efficiency.

                        If the array's length starts at 0, and items are added continually, as
                        in a loop, and the final desired length of the Array could be
                        determined, it might be more efficient to start with an initial load
                        size, greater than the estimated expected size, then trim the array.
                        This would mean that step 10 of Array's [[Put]] could be avoided.

                        9. If ToUint32(P) is less than the value of the length property of A,
                        then return.
                        10. Change (or set) the value of the length property of A to
                        ToUint32(P)+ 1.

                        ^^^ Array [[Put]] - step 10. could be skipped.

                        It's also perfectly valid to omit the - new keyword.

                        var e = Error(),
                        a = Array(200);

                        Yet JSLint complains.

                        It would be useful to have configuration for that feature. So that
                        including a new keyword unnecessarily could be a warning, or vice
                        versa, or could be optional. I always omit new for Error, and I've
                        seen Lasse doing this in posts, too.

                        Of course, it's also valid to use:-

                        var a = [];
                        a.length = 200;

                        Also warnings for throwing primitives, like seen in some pop
                        libraries:

                        throw "type property can't be changed";

                        I would like to have a warning for this. Some browsers provide stack
                        information for thrown objects. These browsers don't provide a stack
                        trace if a primitive is thrown.

                        Garrett

                        Comment

                        • Jorge

                          #13
                          Re: Array constructor or literal

                          On Jun 13, 12:08 am, Douglas Crockford <nos...@sbcglob al.netwrote:
                          >
                               [] and new Array() do the same thing.
                          >
                          And it's a very bad one, indeed : var empty = [];
                          that can turn even worse : empty.push(empt y);
                          Have to have somebody take a look at it *asap*, jejeje.

                          --Jorge.

                          Comment

                          • Thomas 'PointedEars' Lahn

                            #14
                            Re: Array constructor or literal

                            Jorge wrote:
                            On Jun 13, 12:08 am, Douglas Crockford <nos...@sbcglob al.netwrote:
                            > [] and new Array() do the same thing.
                            >
                            And it's a very bad one, indeed : var empty = [];
                            that can turn even worse : empty.push(empt y);
                            Have to have somebody take a look at it *asap*, jejeje.
                            There is no semantical difference between

                            var empty = [];
                            empty.push(empt y);

                            and

                            var empty = new Array();
                            empty.push(empt y);

                            and

                            var empty = Array();
                            empty.push(empt y);

                            What exactly are you getting at?


                            PointedEars
                            --
                            Use any version of Microsoft Frontpage to create your site.
                            (This won't prevent people from viewing your source, but no one
                            will want to steal it.)
                            -- from <http://www.vortex-webdesign.com/help/hidesource.htm>

                            Comment

                            • Duncan Booth

                              #15
                              Re: Array constructor or literal

                              Stevo <no@mail.invali dwrote:
                              Duncan Booth wrote:
                              >Dan Rumney <danrumney@warp mail.netwrote:
                              >>
                              >>I've no problem against JSLint choosing a specific convention and
                              >>applying it. I'm just wondering if there is anything *beyond*
                              >>convention to speak in favour of literal over constructor notation.
                              >>>
                              >I do have issues with some of the other warnings generated by jslint
                              >which is why I produced a modified version that lets you ignore
                              >particular error messages if you don't like them.
                              >
                              I think it's wrong for it to be called jslint when really it should be
                              called jscrockford. It's something that he wrote that highlights
                              anything that doesn't meet his particular coding standards. They're
                              not rules, just preferred styles. Not that I'm saying there's anything
                              wrong with the things it complains about, but they're certainly not
                              all errors. I tried it once and didn't want to change my code in the
                              way necessary to make it happy.
                              >
                              As I recall from my C days, lint was more like a pre-compiler that
                              would tell you what real errors/warnings you have in your code, rather
                              than how it's not suiting one person's style choices. It was used
                              because it was quicker than running the full compiler.
                              >
                              Right. I'm not worried what he calls it, but lint for C warns you about
                              just about every possible thing anyone could object to and you then
                              configure it to only report about the things you don't like. That's what I
                              felt jslint should do. What I came up with is still Crockford's program: I
                              didn't change any of the real guts of his code, all I did was make it
                              configurable and easier to run from the command line and in that way
                              somewhat closer to the original lint concept.

                              Actually the real driver for me to use jslint was that missing out
                              'optional' semicolons confuses some javascript compression programs so I
                              wanted to make sure I had all the optional semicolons in the code. Most of
                              the other warnings I can take or leave, but it did find a few errors such
                              as variables that were accidentally global because of a missing 'var'.

                              Comment

                              Working...