Clarifying scope of literals

Discussion in 'Javascript' started by ociardhp, Oct 25, 2007.

  1. ociardhp

    ociardhp Guest

    Hi

    I've seen some code similar to the following and would like to confirm
    my understanding. I assume the object literal created in the return
    has access to the enclosing scope which includes the variable age,
    effectively creating a closure over it when created, and that this is
    what enables the assignment to moon.age? Is this considered good style
    and is there any particular reason for using that approach as opposed
    to the clearer (in my opinion) declaration of age within the object
    literal?

    Many thanks

    Paul

    <html>
    <body>
    <div id="holder"></div>
    <script>

    moon = function() {
    var age;

    return {
    // age: 4000000000,

    showDarkSide: function() {
    return false;
    }
    }
    }();

    moon.age = 42;

    document.getElementById("holder").innerHTML = "Age: " + moon.age +
    "<br/> ShowDarkSide: " + moon.showDarkSide();

    </script>
    </body>
    </html>
     
    ociardhp, Oct 25, 2007
    #1
    1. Advertising

  2. On Oct 25, 11:29 am, ociardhp <> wrote:
    > I've seen some code similar to the following and would like to confirm
    > my understanding. I assume the object literal created in the return
    > has access to the enclosing scope which includes the variable age,
    > effectively creating a closure over it when created, and that this is
    > what enables the assignment to moon.age? Is this considered good style
    > and is there any particular reason for using that approach as opposed
    > to the clearer (in my opinion) declaration of age within the object
    > literal?


    <snip>

    > <html>
    > <body>


    <snip>

    > <script>
    > moon = function() {
    > var age;
    >
    > return {
    > // age: 4000000000,
    >
    > showDarkSide: function() {
    > return false;
    > }
    > }
    > }();
    >
    > moon.age = 42;
    >
    > document.getElementById("holder").innerHTML = "Age: " + moon.age +
    > "<br/> ShowDarkSide: " + moon.showDarkSide();



    Couple of points to start:
    1. using <script> tags in the <body> of the document is nonstandard
    and should be avoided.
    2. you should always use the "var" keyword to declare your variables
    ("moon" in your example), and it's a good practice to automatically do
    this, even if the variable is global.

    There, now to your question.

    One thing that's perhaps confusing in the discussion of closure and
    scope in JavaScript is that scope is much simpler than you would think
    from a classical OOP language. Your confusion probably comes from mis-
    associating a concept of "private" variables in JavaScript. JS
    doesn't have a "private" concept. Your example effectively creates
    two distinct "things" with the name "age": one is a variable that is
    local to the anonymous function that returns the object that gets
    assigned to "moon"; this object literal has no "age" property until
    you assign it on the next line ("moon.age = 42"). Since "moon" is an
    object, you can always assign values to properties on the object -
    there's no such thing as a "private" property in JavaScript. But the
    "age" property you've created through assignment shouldn't be confused
    with the "age" local variable in the anonymous function's scope.

    Remove that line assigning a value to "moon.age" and re-run your code;
    you'll see what actually happens.

    -David
     
    David Golightly, Oct 25, 2007
    #2
    1. Advertising

  3. ociardhp

    David Mark Guest

    On Oct 25, 2:41 pm, David Golightly <> wrote:
    [snip]
    > 1. using <script> tags in the <body> of the document is nonstandard
    > and should be avoided.


    Non-standard according to who?
     
    David Mark, Oct 25, 2007
    #3
  4. David Golightly wrote:
    > Couple of points to start: 1. using <script> tags in the <body> of the
    > document is nonstandard and should be avoided.


    Utter nonsense.

    > 2. you should always use the "var" keyword to declare your variables
    > ("moon" in your example), and it's a good practice to automatically do
    > this, even if the variable is global.


    If the identifier is not declared, the assignment it will end up as an
    assignment to an enumerable property of an object in the scope chain.
    That does not have to be the Global Object, hence this recommendation.


    PointedEars
     
    Thomas 'PointedEars' Lahn, Oct 25, 2007
    #4
  5. ociardhp

    RobG Guest

    On Oct 26, 4:29 am, ociardhp <> wrote:
    > Hi
    >
    > I've seen some code similar to the following and would like to confirm
    > my understanding. I assume the object literal created in the return
    > has access to the enclosing scope which includes the variable age,
    > effectively creating a closure over it when created, and that this is
    > what enables the assignment to moon.age?


    No (see below).


    > Is this considered good style
    > and is there any particular reason for using that approach as opposed
    > to the clearer (in my opinion) declaration of age within the object
    > literal?


    The pattern is used to emulate the behaviour of private variables that
    can be read or set by priveliged functions:

    <URL: http://www.crockford.com/javascript/private.html >


    [...]
    > <script>
    > moon = function() {
    > var age;


    This variable is local to the anonymous function assigned to moon. It
    can't be directly accessed from outside the function.


    >
    > return {
    > // age: 4000000000,


    Had you not commented out that line, the object returned by the
    function and assigned to moon would have an age property with a value
    of 4000000000. It is a different thing to the local age variable
    declared earlier - they both exist independently.


    > showDarkSide: function() {
    > return false;
    > }


    This function has access to the activation object created by executing
    the "outer" anonymous function, so you could make it a priveliged
    function that gets or sets the value of the private age variable. It
    can also modify the public moon.age property.


    > }
    > }();
    >
    > moon.age = 42;


    Here you create a property of moon called age (if it doesn't already
    exist) and assign it a value of 42.


    --
    Rob
     
    RobG, Oct 26, 2007
    #5
  6. David Golightly a écrit :
    (snip)
    > 1. using <script> tags in the <body> of the document is nonstandard
    > and should be avoided.


    You may want to check the standard before asserting such a thing:

    """
    The SCRIPT element places a script within a document. This element may
    appear any number of times in the HEAD or BODY of an HTML document.
    """
    http://www.w3.org/TR/html4/interact/scripts.html#edef-SCRIPT
     
    Bruno Desthuilliers, Oct 26, 2007
    #6
  7. ociardhp

    ociardhp Guest

    Many thanks for all the informative replies.
    Paul
     
    ociardhp, Oct 26, 2007
    #7
    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. Paul Opal
    Replies:
    12
    Views:
    961
    Paul Opal
    Oct 11, 2004
  2. John Goche
    Replies:
    8
    Views:
    16,468
  3. brooksr
    Replies:
    10
    Views:
    685
    Bob Barrows [MVP]
    Dec 26, 2006
  4. Frank Church
    Replies:
    1
    Views:
    112
    Bob Showalter
    Jun 26, 2007
  5. John Reye

    existance-scope of struct literals

    John Reye, May 1, 2012, in forum: C Programming
    Replies:
    2
    Views:
    339
    Tim Rentsch
    May 8, 2012
Loading...

Share This Page