Recursive object literals in Javascript ?

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

    Recursive object literals in Javascript ?

    Consider:

    var x = {a:3, b:x};

    alert(x.b) ==undefined

    Question: why ?

    x is a pointer to an object, so x.b should refer
    to that same object.

    Theoretically:
    x --some object containing
    a = 3,
    b --x

    However, this is NOT the case. So why is
    x.b "undefined" in JS ?

    --j

  • Michael Wojcik

    #2
    Re: Recursive object literals in Javascript ?

    Richard Cornford wrote:
    java wrote:
    >Consider:
    >>
    >var x = {a:3, b:x};
    >>
    >alert(x.b) ==undefined
    >
    The right hand side of an assignment expression
    is evaluated before the resulting value can be assigned to the left hand
    side (it has to be). So at the point of evaluation the object literal
    the - x - variable has its default - undefined - value, and so that is
    what bets assigned to the object's - b - property.
    Of course, evaluation of x on the RHS can be deferred by wrapping it
    in a closure:

    var x = {a:3, b:function(){re turn x;}};
    alert(x.b().a);

    Obviously that's not the same thing as what the OP was trying to do,
    but it's a common idiom in functional programming.

    Alternatively, with an implementation that supports getters, you can
    provide a getter for b that returns x:

    var x = {a:3};
    x.__defineGette r__("b",functio n(){return this;});
    alert(x.b.a);

    though whether that's good practice is debatable. (And in this
    particular case, I don't think this has any advantage this has over
    simply "x.b=x", as Richard suggested. If you wanted b to evaluate to
    x.a, then the getter would do something for you.)

    If you're using an implementation that supports defining getters in an
    object literal (eg sufficiently recent Mozilla Javascript), then you
    can create a closure that will automatically be evaluated, as part of
    your object literal:

    var x = {a:3, get b(){return this;}};
    alert(x.b.a);

    which achieves the same result as the OP's example. x.b is not
    actually a reference to x, of course; it just returns one when
    evaluated. Though I'm not sure whether a Javascript program can
    distinguish the two.

    --
    Michael Wojcik

    Comment

    • J.S.Criptoff

      #3
      Re: Recursive object literals in Javascript ?

      With an implementation that supports "sharp variables" (non-standard
      notation borrowed from Common Lisp) we can write:

      var x = #1= {a: 3, b: #1#};
      alert(x.b.a); //-3

      Comment

      • Evertjan.

        #4
        Re: Recursive object literals in Javascript ?

        J.S.Criptoff wrote on 19 apr 2008 in comp.lang.javas cript:
        With an implementation that supports "sharp variables" (non-standard
        notation borrowed from Common Lisp) we can write:
        >
        var x = #1= {a: 3, b: #1#};
        alert(x.b.a); //-3
        You cannot borrow from another language,
        [how would you return it?]
        most of us do not lisp.

        --
        Evertjan.
        The Netherlands.
        (Please change the x'es to dots in my emailaddress)

        Comment

        • J.S.Criptoff

          #5
          Re: Recursive object literals in Javascript ?

          On 19 ÁÐÒ, 12:51, "Evertjan." <exjxw.hannivo. ..@interxnl.net wrote:
          J.S.Criptoff wrote on 19 apr 2008 in comp.lang.javas cript:
          >
          With an implementation that supports "sharp variables" (non-standard
          notation borrowed from Common Lisp) we can write:
          >
          var x = #1= {a: 3, b: #1#};
          alert(x.b.a); //-3
          >
          You cannot borrow from another language,
          [how would you return it?]
          most of us do not lisp.
          >
          --
          Evertjan.
          The Netherlands.
          (Please change the x'es to dots in my emailaddress)
          Should I replace word "borrowed" with "stolen"? Anyway "sharp
          variables" do work in FF (SpiderMonkey).

          Comment

          • Richard Cornford

            #6
            Re: Recursive object literals in Javascript ?

            Michael Wojcik wrote:
            Richard Cornford wrote:
            >java wrote:
            >>Consider:
            >>>
            >>var x = {a:3, b:x};
            >>>
            >>alert(x.b) ==undefined
            >>
            >The right hand side of an assignment expression is evaluated before
            >the resulting value can be assigned to
            >the left hand side (it has to be). So at the point of
            >evaluation the object literal the - x - variable has its
            >default - undefined - value, and so that is what bets
            >assigned to the object's - b - property.
            >
            Of course, evaluation of x on the RHS can be deferred by
            wrapping it in a closure:
            >
            var x = {a:3, b:function(){re turn x;}};
            alert(x.b().a);
            >
            Obviously that's not the same thing as what the OP was
            trying to do, but it's a common idiom in functional
            programming.
            >
            Alternatively, with an implementation that supports getters,
            you can provide a getter for b that returns x:
            >
            var x = {a:3};
            x.__defineGette r__("b",functio n(){return this;});
            alert(x.b.a);
            >
            though whether that's good practice is debatable. (And in
            this particular case, I don't think this has any advantage
            this has over simply "x.b=x", as Richard suggested.
            It was Evertjan who posted that suggestion. I think my first suggestion
            would have been that this may be a case for using a constructor to
            create the object rather than an Object literal. I.E.:-

            var x = new SomeObj();

            function SomeObj(){
            this.b = this;
            }
            SomeObj.prototy pe.a = 3;

            - which does not involve creating any more additional function objects
            than your suggestion, and fewer if there are going to be more than one
            such objects created.
            If you wanted b to evaluate to x.a, then the getter would do something
            for you.)
            >
            If you're using an implementation that supports defining
            getters in an object literal (eg sufficiently recent Mozilla
            Javascript), then you can create a closure that will
            automatically be evaluated, as part of your object literal:
            >
            var x = {a:3, get b(){return this;}};
            alert(x.b.a);
            The problem with all of these non-standard language extensions is that
            while you can employ them when writing for a single known implementation
            where they are implemented they are mostly non-practical in a general
            context because they mostly constitute a syntax error where not
            implemented, and there are virtually no practical steps that can be
            taken to detect support for a syntax extension without provoking the
            syntax error wherever it does not exist.

            Richard.


            Comment

            • Michael Wojcik

              #7
              Re: Recursive object literals in Javascript ?

              Richard Cornford wrote:
              Michael Wojcik wrote:
              >Richard Cornford wrote:
              >>java wrote:
              >>>>
              >>>var x = {a:3, b:x};
              >>>>
              >>The right hand side of an assignment expression is evaluated before
              >>the resulting value can be assigned to
              >>the left hand side (it has to be).
              >>
              >Of course, evaluation of x on the RHS can be deferred by
              >wrapping it in a closure:
              >>
              >...
              >>
              >Obviously that's not the same thing as what the OP was
              >trying to do, but it's a common idiom in functional
              >programming.
              >>
              >Alternativel y, with an implementation that supports getters,
              >you can provide a getter for b that returns x:
              >>
              >...
              >>
              >though whether that's good practice is debatable. (And in
              >this particular case, I don't think this has any advantage
              >this has over simply "x.b=x", as Richard suggested.
              >
              It was Evertjan who posted that suggestion.
              Sorry about the misattribution.
              I think my first suggestion
              would have been that this may be a case for using a constructor to
              create the object rather than an Object literal.
              Agreed. In this case I was interested in the OP's question, rather
              than better ways to accomplish the same result.
              >If you're using an implementation that supports defining
              >getters in an object literal ...
              >
              The problem with all of these non-standard language extensions is that
              while you can employ them when writing for a single known implementation
              where they are implemented they are mostly non-practical in a general
              context because they mostly constitute a syntax error where not
              implemented, and there are virtually no practical steps that can be
              taken to detect support for a syntax extension without provoking the
              syntax error wherever it does not exist.
              Agreed again, in the general case. Some of the Javascript I write
              explicitly targets specific implementations , just like some of the
              programs I write in other languages.

              --
              Michael Wojcik

              Comment

              Working...