Loading ...
Sorry, an error occurred while loading the content.

json.js breaks for-in loops

Expand Messages
  • Peter Michaux
    Hi, By extending the Object.prototype with the new property toJSONString I can no longer use for-in loops in my JavaScript. Has someone released a version of
    Message 1 of 10 , Oct 13, 2006
    • 0 Attachment
      Hi,

      By extending the Object.prototype with the new property toJSONString I
      can no longer use for-in loops in my JavaScript.

      Has someone released a version of JSON that doesn't do this?

      Is it just as simple as changing these

      Object.prototype.toJSONString = function () {
      Array.prototype.toJSONString = function () {
      String.prototype.parseJSON = function () {

      to something like

      JSON.objectToJSONString = function () {
      JSON.arrayToJSONString = function () {
      JSON.parseJSON = function () {

      or are their other catches that I have missed?

      Thank you,
      Peter
    • Philip Tellis
      ... this is a design flaw in Javascript. You need to check the hasOwnProperty() method when iterating in a for..in loop: for(k in obj)
      Message 2 of 10 , Oct 14, 2006
      • 0 Attachment
        Sometime on Oct 13, PM cobbled together some glyphs to say:

        > By extending the Object.prototype with the new property toJSONString I
        > can no longer use for-in loops in my JavaScript.

        this is a design flaw in Javascript. You need to check the
        hasOwnProperty() method when iterating in a for..in loop:

        for(k in obj)
        if(obj.hasOwnProperty(k))
        foo(k);

        --
        How often I found where I should be going only by setting out for somewhere
        else.
        -- R. Buckminster Fuller
      • Tom Metro
        ... As another poster mentioned, using hasOwnProperty(), is the way to make the intended behavior work. My understanding is that hasOwnProperty() isn t widely
        Message 3 of 10 , Oct 14, 2006
        • 0 Attachment
          Peter Michaux wrote:
          > By extending the Object.prototype with the new property toJSONString I
          > can no longer use for-in loops in my JavaScript.

          As another poster mentioned, using hasOwnProperty(), is the way to make
          the intended behavior work. My understanding is that hasOwnProperty()
          isn't widely supported yet.


          > Has someone released a version of JSON that doesn't do this?

          I thought I remembered seeing a version that had a flag controlling
          whether the methods got added to the stock objects, but clearly that
          isn't in the current version of the code. I think I was thinking of
          another library... It'd be a worthy enhancement for the json.js library.


          > Is it just as simple as changing these
          > Object.prototype.toJSONString = function () {
          >...
          > to something like
          > JSON.objectToJSONString = function () {

          It looks like that should work. The code itself doesn't seem to
          recursively use those method names, instead using s[object type] internally.

          -Tom

          --
          Tom Metro
          Venture Logic, Newton, MA, USA
          "Enterprise solutions through open source."
          Professional Profile: http://tmetro.venturelogic.com/
        • Scott Chapman
          It s easy to modify json.js so it doesn t extend Object.prototype. That was a bad design in my opinion. The version I use is attached. Scott ... [Non-text
          Message 4 of 10 , Oct 14, 2006
          • 0 Attachment
            It's easy to modify json.js so it doesn't extend Object.prototype. That was a
            bad design in my opinion.

            The version I use is attached.

            Scott

            Peter Michaux wrote:
            > Hi,
            >
            > By extending the Object.prototype with the new property toJSONString I
            > can no longer use for-in loops in my JavaScript.
            >
            > Has someone released a version of JSON that doesn't do this?
            >
            > Is it just as simple as changing these
            >
            > Object.prototype.toJSONString = function () {
            > Array.prototype.toJSONString = function () {
            > String.prototype.parseJSON = function () {
            >
            > to something like
            >
            > JSON.objectToJSONString = function () {
            > JSON.arrayToJSONString = function () {
            > JSON.parseJSON = function () {
            >
            > or are their other catches that I have missed?
            >
            > Thank you,
            > Peter



            [Non-text portions of this message have been removed]
          • Martin Cooper
            ... It s not just exceptionally bad design, it s chronically inconsiderate programming. Nobody could use that code inside portlets, because they d risk
            Message 5 of 10 , Oct 14, 2006
            • 0 Attachment
              On 10/14/06, Scott Chapman <scott_list@...> wrote:
              >
              > It's easy to modify json.js so it doesn't extend Object.prototype. That
              > was a
              > bad design in my opinion.


              It's not just exceptionally bad design, it's chronically inconsiderate
              programming. Nobody could use that code inside portlets, because they'd risk
              breaking any and all other JavaScript on the same portal page over which
              they have no control. Even outside a portal environment, it's going to break
              other libraries that developers might already be using, not to mention their
              own code.

              --
              Martin Cooper


              The version I use is attached.
              >
              > Scott
              >
              > Peter Michaux wrote:
              > > Hi,
              > >
              > > By extending the Object.prototype with the new property toJSONString I
              > > can no longer use for-in loops in my JavaScript.
              > >
              > > Has someone released a version of JSON that doesn't do this?
              > >
              > > Is it just as simple as changing these
              > >
              > > Object.prototype.toJSONString = function () {
              > > Array.prototype.toJSONString = function () {
              > > String.prototype.parseJSON = function () {
              > >
              > > to something like
              > >
              > > JSON.objectToJSONString = function () {
              > > JSON.arrayToJSONString = function () {
              > > JSON.parseJSON = function () {
              > >
              > > or are their other catches that I have missed?
              > >
              > > Thank you,
              > > Peter
              >
              >
              >
              > [Non-text portions of this message have been removed]
              >
              >
              >
              >
              > Yahoo! Groups Links
              >
              >
              >
              >
              >
              >


              [Non-text portions of this message have been removed]
            • Stephen M. McKamey
              ... toJSONString I ... make ... A little late to the conversation but... another alternative could be to use the typeof operator (assuming one was iterating
              Message 6 of 10 , Nov 13, 2006
              • 0 Attachment
                --- In json@yahoogroups.com, Tom Metro <tmetro+json@...> wrote:
                >
                > Peter Michaux wrote:
                > > By extending the Object.prototype with the new property
                toJSONString I
                > > can no longer use for-in loops in my JavaScript.
                >
                > As another poster mentioned, using hasOwnProperty(), is the way to
                make
                > the intended behavior work. My understanding is that hasOwnProperty()
                > isn't widely supported yet.

                A little late to the conversation but... another alternative could be
                to use the typeof operator (assuming one was iterating over data):

                for(k in obj)
                if("function"!=typeof obj[k])
                foo(k);

                Thanks,
                smm
              • Martin Cooper
                ... Sure - if the for loop is in your own code, and not some other package that you re just trying to make use of. This issue really needs to be fixed in the
                Message 7 of 10 , Nov 13, 2006
                • 0 Attachment
                  On 11/13/06, Stephen M. McKamey <jsonml@...> wrote:
                  >
                  > --- In json@yahoogroups.com, Tom Metro <tmetro+json@...> wrote:
                  > >
                  > > Peter Michaux wrote:
                  > > > By extending the Object.prototype with the new property
                  > toJSONString I
                  > > > can no longer use for-in loops in my JavaScript.
                  > >
                  > > As another poster mentioned, using hasOwnProperty(), is the way to
                  > make
                  > > the intended behavior work. My understanding is that hasOwnProperty()
                  > > isn't widely supported yet.
                  >
                  > A little late to the conversation but... another alternative could be
                  > to use the typeof operator (assuming one was iterating over data):
                  >
                  > for(k in obj)
                  > if("function"!=typeof obj[k])
                  > foo(k);


                  Sure - if the for loop is in your own code, and not some other package that
                  you're just trying to make use of.

                  This issue really needs to be fixed in the JSON code, since there's no way
                  you can rely on it being fixed in all the other code out there that you
                  might want to use.

                  --
                  Martin Cooper


                  Thanks,
                  > smm
                  >
                  >
                  >
                  >
                  >
                  > Yahoo! Groups Links
                  >
                  >
                  >
                  >
                  >


                  [Non-text portions of this message have been removed]
                • Stephen M. McKamey
                  // This should do what you are asking for while staying // current with Crockford s latest code: // after json.js has loaded... // define a namespace to
                  Message 8 of 10 , Nov 13, 2006
                  • 0 Attachment
                    // This should do what you are asking for while staying
                    // current with Crockford's latest code:

                    // after json.js has loaded...
                    // define a namespace to minimize footprint
                    var JSON = {};

                    // add all of the methods
                    JSON.arrayToJSONString = Array.prototype.toJSONString;
                    JSON.booleanToJSONString = Boolean.prototype.toJSONString;
                    JSON.dateToJSONString = Date.prototype.toJSONString;
                    JSON.numberToJSONString = Number.prototype.toJSONString;
                    JSON.objectToJSONString = Object.prototype.toJSONString;
                    JSON.stringToJSONString = String.prototype.toJSONString;
                    JSON.parseJSON = String.prototype.parseJSON;

                    // remove all the methods from intrinsic objects
                    delete(Array.prototype.toJSONString);
                    delete(Boolean.prototype.toJSONString);
                    delete(Date.prototype.toJSONString);
                    delete(Number.prototype.toJSONString);
                    delete(Object.prototype.toJSONString);
                    delete(String.prototype.toJSONString);
                    delete(String.prototype.parseJSON);

                    --- In json@yahoogroups.com, "Martin Cooper" <mfncooper@...> wrote:
                    > Sure - if the for loop is in your own code, and not some other
                    package that
                    > you're just trying to make use of.
                    >
                    > This issue really needs to be fixed in the JSON code, since there's
                    no way
                    > you can rely on it being fixed in all the other code out there that
                    you
                    > might want to use.
                  • Martin Cooper
                    ... Right. But I don t understand the resistance (or, actually, just lack of any feedback at all) to having the kind of solution I described before (in another
                    Message 9 of 10 , Nov 13, 2006
                    • 0 Attachment
                      On 11/13/06, Stephen M. McKamey <jsonml@...> wrote:
                      >
                      > // This should do what you are asking for while staying
                      > // current with Crockford's latest code:


                      Right. But I don't understand the resistance (or, actually, just lack of any
                      feedback at all) to having the kind of solution I described before (in
                      another thread) incorporated into the original source code, so that we don't
                      have to be going and deleting things like that. Here's what I suggested
                      before, which is largely the same as yours, except that mine avoids creation
                      where yours utilises deletion and is necessarily separate (and hence a
                      little less easily maintained) from the original:

                      http://tech.groups.yahoo.com/group/json/message/557

                      --
                      Martin Cooper


                      // after json.js has loaded...
                      > // define a namespace to minimize footprint
                      > var JSON = {};
                      >
                      > // add all of the methods
                      > JSON.arrayToJSONString = Array.prototype.toJSONString;
                      > JSON.booleanToJSONString = Boolean.prototype.toJSONString;
                      > JSON.dateToJSONString = Date.prototype.toJSONString;
                      > JSON.numberToJSONString = Number.prototype.toJSONString;
                      > JSON.objectToJSONString = Object.prototype.toJSONString;
                      > JSON.stringToJSONString = String.prototype.toJSONString;
                      > JSON.parseJSON = String.prototype.parseJSON;
                      >
                      > // remove all the methods from intrinsic objects
                      > delete(Array.prototype.toJSONString);
                      > delete(Boolean.prototype.toJSONString);
                      > delete(Date.prototype.toJSONString);
                      > delete(Number.prototype.toJSONString);
                      > delete(Object.prototype.toJSONString);
                      > delete(String.prototype.toJSONString);
                      > delete(String.prototype.parseJSON);
                      >
                      > --- In json@yahoogroups.com, "Martin Cooper" <mfncooper@...> wrote:
                      > > Sure - if the for loop is in your own code, and not some other
                      > package that
                      > > you're just trying to make use of.
                      > >
                      > > This issue really needs to be fixed in the JSON code, since there's
                      > no way
                      > > you can rely on it being fixed in all the other code out there that
                      > you
                      > > might want to use.
                      >
                      >
                      >
                      >
                      >
                      >
                      > Yahoo! Groups Links
                      >
                      >
                      >
                      >
                      >


                      [Non-text portions of this message have been removed]
                    • Douglas Crockford
                      JavaScript is an imperfect language. The weird interaction between augmentation of prototypes with the for..in statement is evidence of this. This defect in
                      Message 10 of 10 , Nov 14, 2006
                      • 0 Attachment
                        JavaScript is an imperfect language. The weird interaction between
                        augmentation of prototypes with the for..in statement is evidence of
                        this. This defect in the language requires that for..in blocks
                        explicitly filter out unwanted stuff that is dredged up from the
                        prototype chain. See http://yuiblog.com/blog/2006/09/26/for-in-intrigue/

                        json.js provides the same API that will be built into ECMAScript
                        Fourth Edition. That means that if your program works with json.js,
                        then it will work even better when the language is revised.

                        Some people do not have the luxury of being forward looking. They have
                        to work with bad code that does not filter for..in, or they claim the
                        right to write bad code themselves. Those people should not be using
                        json.js. Fortunately, JSON encoding and decoding is so easy, there
                        isn't much effort required to make an implementation that works with
                        bad code.

                        JSON is a standard data representation. The json.js implementation is
                        not the standard. It is a reference implementation. You are free to
                        use it in any way that you want, or to not use it.
                      Your message has been successfully submitted and would be delivered to recipients shortly.