Scope Chains and Method Invocation.

Discussion in 'Javascript' started by emailscotta@gmail.com, Nov 10, 2006.

  1. Guest

    After reading Richard's article,
    http://www.jibbering.com/faq/faq_notes/closures.html, I would like to
    re-visit an earlier post of mine. I think I know understand why the
    code doesn't work but would like to get some verification. Below is
    some code and below that is an explanation of what I think is
    happening.

    var SomeObj = {
    doSomething : function()
    {
    return 'Did something';
    },

    useDoSomething : function()
    {
    //Doesn't work - doSomething() not defined.
    return doSomething();
    //Works
    //return this.doSomething();
    //Works
    //return SomeObj.doSomething();
    }

    }

    document.writeln(obj.doSomething());
    document.writeln(obj.useDoSomething());


    1) Global Variable Instantiation
    - A named property of the global object is created, SomeObj.
    - But the object is not created until the assignment statement
    is executed.

    2) Code execution begins
    - assignment statement var SomeObj = {....} is executed.
    - an execution context is created.
    - SomeObj is created with a [[scope]] contain only the
    global object.
    - Variable instantiation creates 2 named properties
    doSomething and useDoSomething.

    (Here where I think I'm going wrong)

    - doSomething is created with a [[scope]]
    containing SomeObj --> global object.
    - useDoSomething is created with a [[scope]]
    containing SomeObj --> global object.


    Since the code does not work SomeObj can not be on the scope chain and
    scope chain for doSomething and useDoSomething must only contain the
    global object.


    I would also like to ask VK to refrain from replying to this message.
    It seems that when Richard and VK get together an argument breaks out
    and the question get lost. Sorry if this offend either of you I just
    want to get my question answer.

    Thanks for any help!
     
    , Nov 10, 2006
    #1
    1. Advertising

  2. Matt Kruse Guest

    wrote:
    > var SomeObj = {
    > doSomething : function(){return 'Did something';},
    > useDoSomething : function(){
    > //Doesn't work - doSomething() not defined.
    > return doSomething();
    > //Works
    > //return this.doSomething();
    > //Works
    > //return SomeObj.doSomething();
    > }
    > }
    > 2) Code execution begins
    > - assignment statement var SomeObj = {....} is executed.
    > - an execution context is created.


    A function hasn't been entered, so no execution context needs to be created.
    Object creation does not create an execution context.

    > (Here where I think I'm going wrong)
    > - doSomething is created with a [[scope]]
    > containing SomeObj --> global object.


    SomeObj is not in the scope chain, since it's just an object.

    Now back to your original attempts:

    > //Doesn't work - doSomething() not defined.
    > return doSomething();


    Since doSomething is a property of the same object where useDoSomething
    exists, it won't be found. The object is not part of the scope chain.

    > //Works
    > //return this.doSomething();


    Since 'this' refers to the object, this resolves specifically to the right
    place and specifies the attribute to resolve.

    > //Works
    > //return SomeObj.doSomething();


    Same here, but instead of resolving with 'this' you're resolving using the
    attribute in the global namespace.

    This may be more of what you're looking for:

    var SomeObj = (function(){
    function doSomething(){return 'Did something';}
    return {
    useDoSomething : function(){
    return doSomething();
    }
    }
    })();
    alert(SomeObj.useDoSomething());

    This creates and runs a function, which creates a new execution context. The
    doSomething function inside is only visible to things defined within the
    execution context, so doSomething is in effect a private method.

    Then an object is returned, which will be assigned to the SomeObj attribute
    of the global object. In its scope chain is the anonymous function which
    contains the doSomething function. So when doSomething() is fired from
    within the useDoSomething function, it finds doSomething in its scope chain.
    Since this object is returned, containing the anonymous function execution
    context, and the outer anonymous function is executed, this creates the
    closure. Since the execution context of the anonymous outer function is
    still in the scope chain of the useDoSomething function, it has to continue
    to exist, and take doSomething along for the ride.

    I hope I was fairly clear. Richard may explain better, since a fair amount
    of what I know on the topic I actually learned from him ;)

    --
    Matt Kruse
    http://www.JavascriptToolbox.com
    http://www.AjaxToolbox.com
     
    Matt Kruse, Nov 10, 2006
    #2
    1. Advertising

  3. [Apologies if this is double-posted]

    wrote:

    [snip]

    > var SomeObj = {
    > doSomething : function()
    > {
    > return 'Did something';
    > },
    >
    > useDoSomething : function()
    > {
    > //Doesn't work - doSomething() not defined.
    > return doSomething();
    > //Works
    > //return this.doSomething();
    > //Works
    > //return SomeObj.doSomething();
    > }
    >
    > }
    >
    > document.writeln(obj.doSomething());
    > document.writeln(obj.useDoSomething());
    >
    >
    > 1) Global Variable Instantiation
    > - A named property of the global object is created, SomeObj.
    > - But the object is not created until the assignment statement
    > is executed.


    Yes. Variable declarations are processed before execution begins upon
    entering an execution context. This results in the creation of
    properties on the relevant variable object. However, any initialisers
    are delayed until they are evaluated.

    When evaluating "global" code, the variable object is the global object
    itself.

    > 2) Code execution begins
    > - assignment statement var SomeObj = {....} is executed.
    > - an execution context is created.


    No. There is a running execution context - the one created when
    executing global code - but that is the only execution context that
    currently exists.

    Object literals do not create execution contexts. Further execution
    contexts are entered only by calling functions or constructors.

    > - SomeObj is created with a [[scope]] contain only the
    > global object.
    > - Variable instantiation creates 2 named properties
    > doSomething and useDoSomething.


    Neither of those are correct, for the reason given above: evaluating an
    object literal does not result in entering a new execution context.

    An object literal creates a new object, as if by

    new Object()

    The comma-separated list of property names and values is then added to
    that new object. The evaluation of

    var object = { property : 'value' };

    is equivalent to:

    var object = new Object();

    object.property = 'value';

    Even if that string literal was replaced with a function expression,
    there is nothing here that would cause its [[Scope]] property to contain
    more than just the global object.

    > (Here where I think I'm going wrong)
    >
    > - doSomething is created with a [[scope]]
    > containing SomeObj --> global object.
    > - useDoSomething is created with a [[scope]]
    > containing SomeObj --> global object.


    Yes, that is wrong,

    > Since the code does not work SomeObj can not be on the scope chain and
    > scope chain for doSomething and useDoSomething must only contain the
    > global object.


    .... and your reasoning is spot on.

    [snip]

    > Thanks for any help!


    I hope that helps,
    Mike
     
    Michael Winter, Nov 11, 2006
    #3
  4. wrote:
    > After reading Richard's article,
    > http://www.jibbering.com/faq/faq_notes/closures.html, I would
    > like to re-visit an earlier post of mine. I think I know
    > understand why the code doesn't work but would like to get
    > some verification. Below is some code and below that is an
    > explanation of what I think is happening.
    >
    > var SomeObj = {
    > doSomething : function()
    > {
    > return 'Did something';
    > },
    >
    > useDoSomething : function()
    > {
    > //Doesn't work - doSomething() not defined.
    > return doSomething();
    > //Works
    > //return this.doSomething();
    > //Works
    > //return SomeObj.doSomething();


    Although this will work it is not the way to do it as you should avoid
    linking the Identifier - SomeObj - to the code within the value assigned
    to that Identifier. When a method of an object is being called/employed
    as a method of that object the code it contains should refer to the
    object instance using the - this - keyword. That makes for more easily
    portable and maintainable code as then the same structure can be employed
    elsewhere or the Identifier changed, without having to go looking for all
    the references to it in the contained code.

    > }
    >
    > }
    >
    > document.writeln(obj.doSomething());
    > document.writeln(obj.useDoSomething());
    >
    >
    > 1) Global Variable Instantiation
    > - A named property of the global object is created, SomeObj.


    And as it is a declared variable the property is gi9ven the -
    DontDelete - attribute (so it cannot be deleted from the global object).
    The value of the property is also provisionally given the Undefined value
    as all existing properties must have a value.

    > - But the object is not created until the assignment
    > statement is executed.


    Correct.

    > 2) Code execution begins
    > - assignment statement var SomeObj = {....} is executed.
    > - an execution context is created.


    An execution context (the global execution context) is created prior to
    variable instantiation, which itself precedes the execution of any code
    within the execution context, and so must happen prior to the assignment
    operation being executed. No new execution context is created for the
    evaluation of an object literal/intialiser.

    > - SomeObj is created with a [[scope]] contain only the
    > global object.


    SomeObj - is just an normal object and normal object don't have [[Scope]]
    properties. The two function objects created by the evaluation of the
    FunctionExpressions within the object literal/initialiser do have
    [[Scope]] properties, and those [[Scope]] properties both refer to a
    scope chain that only includes the global object.

    > - Variable instantiation creates 2 named properties
    > doSomething and useDoSomething.


    There is no variable instantiation in the evaluation of an object
    literal/initialiser. The evaluation of such a construct involves the
    creation of an object equivalent to a call to - new Object(); - and the
    creation of properties of that object who's names correspond with the
    Identifiers/string literals or numeric literals to the left of the colons
    in the object literal and with the values assigned to those properties
    having the value resulting from the evaluation of the Expressions to the
    right of the colons.

    This is, in this case an object is created equivalent to a call to - new
    Object(); - and that object is given a property named "doSomething", the
    FunctionExpression of - function(){return 'Did something';} - is
    evaluated, resulting in the creation of a new Function object, and the
    value of that Function object (a reference to the function object) is
    assigned to the - doSomething - property of the object. And then much the
    same happens for the "useDoSomething" property.

    > (Here where I think I'm going wrong)
    >
    > - doSomething is created with a [[scope]]
    > containing SomeObj --> global object.


    It is not. At no point does the object eventually referred to by the -
    SomeObj - property of the global object find itself on the scope chain.
    The [[Scope]] property of the Function object refers to a scope chain
    that only contains the global object, because that is the scope chain of
    the (global) execution context in which the Function object was created.

    > - useDoSomething is created with a [[scope]]
    > containing SomeObj --> global object.


    Ditto.

    > Since the code does not work SomeObj can not be on the
    > scope chain and scope chain for doSomething and
    > useDoSomething must only contain the global object.


    Yes, - SomeObj - is not on the scope chain of those function's execution
    contexts when you run them.

    Keep in mind that the scope chains that belong to execution contexts are
    used to resolve Identifiers in code executed within those contexts, as
    the source of the [[Scope]] properties of Function objects created within
    those execution contexts and for nothing else. And that only Function
    objects have [[Scope]] properties as [[Scope]] properties are only used
    to define the scope chains used for their execution contexts when the
    functions are executed. That is the extent of the role of scope chains
    and [[Scope]] properties in javascript.

    > I would also like to ask VK to refrain from replying to
    > this message.
    > It seems that when Richard and VK get together an argument
    > breaks out and the question get lost. Sorry if this offend
    > either of you I just want to get my question answer.


    Why should I be offended that you reject VK's nonsense. Indeed if more
    people told VK what they thought of his 'contributions' he might find it
    harder to dismiss the correction of his technical ignorance as the
    product of prejudice, and actually see the need to learn something about
    javascript before pontificating on the subject.

    Richard.
     
    Richard Cornford, Nov 11, 2006
    #4
  5. Guest

    Thanks for everyones help!
     
    , Nov 13, 2006
    #5
    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. Matt
    Replies:
    2
    Views:
    491
    Chris Smith
    Jul 1, 2004
  2. plork123

    handlers and chains

    plork123, May 13, 2005, in forum: Java
    Replies:
    0
    Views:
    319
    plork123
    May 13, 2005
  3. Replies:
    1
    Views:
    3,184
    bruce barker \(sqlwork.com\)
    May 11, 2006
  4. Stefan Ram
    Replies:
    3
    Views:
    838
    Daniel Pitts
    Oct 2, 2007
  5. hsfd cvxbfd
    Replies:
    0
    Views:
    108
    hsfd cvxbfd
    Dec 5, 2010
Loading...

Share This Page