Another Object literal Question!

Discussion in 'Javascript' started by emailscotta@gmail.com, Oct 17, 2006.

  1. Guest

    Below I declared a basic object literal with 2 methods. The
    "doSomething" method is call from the "useDoSomething" method but the
    call is only sucessful if I use the "this" keyword or qualify the call
    with "SomeObj".

    Can someone describe why this is happening?

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

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

    alert(SomeObj.doSomething());
    alert(SomeObj.useDoSomething());
     
    , Oct 17, 2006
    #1
    1. Advertising

  2. RobG Guest

    wrote:
    > Below I declared a basic object literal with 2 methods. The
    > "doSomething" method is call from the "useDoSomething" method but the
    > call is only sucessful if I use the "this" keyword or qualify the call
    > with "SomeObj".
    >
    > Can someone describe why this is happening?
    >
    > var SomeObj = {
    > doSomething : function()
    > {
    > return 'Did something';
    > },
    >
    > useDoSomething : function()
    > {
    > //Doesn't work - doSomething() no defined.
    > return doSomething();
    > //Works
    > //return this.doSomething();
    > //Works
    > //return SomeObj.doSomething();
    > }
    > }
    >
    > alert(SomeObj.doSomething());
    > alert(SomeObj.useDoSomething());


    This thread may help:

    <URL:
    http://groups.google.com/group/comp...le scope and closures&rnum=1#d2a7ee1707cd0a9a
    >


    --
    Rob
     
    RobG, Oct 18, 2006
    #2
    1. Advertising

  3. RobG Guest

    RobG, Oct 18, 2006
    #3
  4. Guest

    I'm still a little confused because I don't see where any closures are
    formed.

    I am unsure of why an one method of an object literal does not have
    access to another method of the same object literal.

    I'm probably not explain myself very well, sorry!


    RobG wrote:
    > RobG wrote:
    > [...]
    > > This thread may help:

    >
    > Actually a better reference is Richard's closures article, it is very
    > comprehensive. It covers much more than just closures:
    >
    > <URL: http://www.jibbering.com/faq/faq_notes/closures.html >
    >
    >
    > --
    > Rob
     
    , Oct 25, 2006
    #4
  5. wrote:

    > I'm still a little confused because I don't see where any closures
    > are formed.


    There aren't any in the code you posted.

    > I am unsure of why an one method of an object literal does not have
    > access to another method of the same object literal.


    The properties of an object literal do not affect the scope chain. The
    property is only added to the newly-created object itself, and will only
    be visible if accessed through that object using the this operator or
    some other reference.

    Though the closures article in the FAQ notes isn't directly relevant, it
    does discuss how the scope chain is constructed and how properties are
    added to the objects in that chain. Only the means described therein -
    formal arguments, function declarations, and variable declarations -
    perform the latter.

    [snip]

    Mike


    Please do not top-post when replying to this group.
     
    Michael Winter, Oct 26, 2006
    #5
  6. RobG Guest

    wrote:
    > I'm still a little confused because I don't see where any closures are
    > formed.


    Please don't top post, reply below trimmed quotes.

    The function statements themselves don't create any closures. The
    article I referred to has some good information on how functions are
    instantiated, I didn't mean to set you on down the wrong path.


    > I am unsure of why an one method of an object literal does not have
    > access to another method of the same object literal.


    The scope of function objects is based on their prototype chain and is
    defined when you declare the function, though you can change it by
    subsequently modifying the prototype chain. In your object literal,
    you don't place SomeObj on the function's scope chain, therefore its
    properties are not available to the function.

    The this keyword is given a value *when the function is called* that is
    a reference to the object that the function is being called as a method
    of. In your original post you had:

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

    If you do:

    var anotherObj = {};
    anotherObj.useDoSomething = SomeObj.useDoSomething;
    anotherObj.useDoSomething();

    you'll get an error, because when called as a method of anotherObj,
    useDoSomething's this keyword will point to anotherObj, which doesn't
    have a doSomething method.


    > > Actually a better reference is Richard's closures article, it is very
    > > comprehensive. It covers much more than just closures:


    It covers quite a bit on what happens when function objects are created
    and called.


    --
    Rob
     
    RobG, Oct 26, 2006
    #6
  7. VK Guest

    The provided resources contain a lot of useful info about JavaScript
    closures and function/method functioning. I suggest to read them and
    even bookmark them.

    Still in more direct relation with difficulties which you are
    experiencing is the distinction between CURRENT OBJECT and DEFAULT
    OBJECT and their semi non-orthodoxy implementation in JavaScript.

    The current object is always pointed by [this] keyword. Picturally (but
    unofficially) it could be said that [this] points to whoever requested
    at this time to execute the current chunk of code. In your sample
    SomeObj is the one who requested useDoSomething execution and [this]
    points to SomeObj.

    The default object is the object where the engine searches first for
    requested properties (against of what it tries to resolve the given
    identifier): if no other object was explicitly indicated. Picturally
    (but unofficially) if you say "go get me that" and if you did not
    specify exactly where to get it, the default object will be the first
    place the engine will search. More officially the default object is the
    one placed at the top of the scope chain (where the bottom of this
    chain is always points to the global scope). If the requested property
    is not presented in the local scope, the engine goes further by the
    scope chain and it looks at the global scope. If still no luck then the
    engine gives up and it errors out.
    Because instead of
    window.alert('Hi!')
    window.document.write('Hi!')
    we can (and mostly do) use
    alert('Hi!')
    document.write('Hi!')
    some language references state that [window] object *is* the default
    object by default. That is an error. [window] object has nothing to do
    with the default object; but because [window] and Global object are
    made to act as one unit, the engine will find window fields and methods
    at the end of the scope chain, just like it finds variable foo in
    var foo = 'bar';
    function f() {
    alert(foo);
    }
    The resolution of 'alert' and 'foo' identifiers above goes by
    equivalent schema: with searching 'alert' and 'foo' in the local scope,
    failing - then finding them in the global scope. That is why in
    time-crucial applications (say graphics intensive ones) it is a good
    idea to use fully-qualified path to window methods: it saves the engine
    from searching and failing first in the local scope. Depending on the
    complexity of the local scope structure the productivity gain for
    looped calls can be very noticeable.

    In some languages current object and default object are made to act in
    relay thus if an identifier cannot be resolved against default object
    it will be tried against current object. Some languages have default
    object accessor shortcut (dot - member name). JavaScript doesn't
    implement the first and it doesn't have the second. In JavaScript
    current object and default object are two totally separate programming
    entities.

    With this in mind you can now explain yourself now the engine behavior:

    1)
    useDoSomething : function()
    {
    return doSomething();
    }
    No object is indicated, so the engine first looking for doSomething in
    the local function scope. It doesn't find it there so it looks for
    doSomething in the global scope; still no luck == error.
    That is an overall bad idea: but just to stress once again the
    difference between current and default objects you could "fix" this
    code by forcing both current and default objects to point to the same
    object:
    useDoSomething : function()
    {
    with (this) {
    return doSomething();
    }
    }

    2)
    useDoSomething : function()
    {
    return this.doSomething();
    }
    The engine searches for doSomething in the current object which is set
    to SomeObj in this case. Success!

    3)
    useDoSomething : function()
    {
    return SomeObj.doSomething();
    }
    The engine searches for doSomething in the explicitly indicated object
    SomeObj. Success once again.

    The behavioral difference between 2) and 3) is that current object is
    not always the same object which you have initially assigned property
    to. As I pointed out in another post, JavaScript doesn't have ideas of
    "private property" and "exclusive ownership" as such :) The fact that
    you assign a reference to anonymous function to SomeObj.useDoSomething
    property - this fact doesn't create any exclusive relations between
    SomeObj, useDoSomething and the said anonymous function. Any amount of
    other objects can get a reference to this function and respectively
    current object ([this] value) will be set to these objects during the
    function execution:

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

    useDoSomething : function()
    {
    return this.doSomething();
    }
    }

    alert(SomeObj.useDoSomething());

    var OtherObj = new Object();
    OtherObj.doSomething = function() {return 'OtherObj';}
    OtherObj.useDoSomething = SomeObj.useDoSomething;
    alert(OtherObj.useDoSomething());

    Practically it means:
    1) If your object is a singleton (it is supposed to be only one
    instance of this object in the whole execution context) you may want to
    use the singleton name instead of [this] inside its methods. This way
    if someone assigns a reference to a singleton method to another object
    (just like above) the method behavior will be most probably
    dissatisfactory for the "borrower".
    2) In any other case [this] is preferable and often the only one usable
    alternative.
     
    VK, Oct 26, 2006
    #7
  8. VK wrote:
    > The provided resources contain a lot of useful info about
    > JavaScript closures and function/method functioning. I
    > suggest to read them and even bookmark them.


    I suggest that as some point _you_ try reading and _understanding_ them,
    as bookmaking then is hardly a useful substitute.

    <snip>
    > .... More officially the default object is the one placed
    > at the top of the scope chain (where the bottom of this
    > chain is always points to the global scope). If the
    > requested property


    "Requested property" is potentially confusing and misleading. The _only_
    constructs in javascript that are resolved against the scope chain are
    Identifiers, while 'requesting' a 'property' would be implied in property
    accessor resolution.

    > is not presented in the local scope,
    > the engine goes further by the scope chain and it looks
    > at the global scope. If still no luck then the engine gives
    > up and it errors out.
    > Because instead of
    > window.alert('Hi!')
    > window.document.write('Hi!')
    > we can (and mostly do) use
    > alert('Hi!')
    > document.write('Hi!')
    > some language references state that [window] object *is* the
    > default object by default. That is an error.


    Are you saying that some references state that the window object is the
    first object on the scope chin by default (whatever "by default" is
    supposed to mean in this context)? You can cite these "references"?

    Of course if you insist on using "default object" as a label for the
    object at the top of the scope chain then the window/global object is the
    "default object" in the global execution context. And as the global
    execution context is the execution context that code always first enters,
    and so may be regarded as the "default" (entering any other execution
    context requires explicit scripted instructions), it would be true to say
    that window/global object is at the top of the scope chain' by default'.

    > [window] object has nothing to do
    > with the default object;


    Apart from being the object at the top of the scope chain (your "default
    object") in the ('default') global exect5uion context.

    > but because [window] and Global object are
    > made to act as one unit,


    There is no practical sense in which they are not the same object.

    > the engine will find window fields and
    > methods at the end of the scope chain, just like it
    > finds variable


    Which is what would be expected if they are the same object.

    > foo in var foo = 'bar';
    > function f() {
    > alert(foo);
    > }
    > The resolution of 'alert' and 'foo' identifiers above
    > goes by equivalent schema: with searching 'alert' and
    > 'foo' in the local scope, failing - then finding them
    > in the global scope.



    The whole mechanism of closures relies on the fact that there may be more
    than two objects on the scope chain. What you are referring to as "the
    local scope" is the Activation/Variable at the top of the scope chain
    (the thing that would be your "default object" by default). there may be
    numerous other Activation/Variable objects on the scope chain (along with
    any objects added deliberately added to the scope chain of functions
    using the - with - statements).

    The indefinite length of the scope chain, and the fact that Identifier
    resolution works down the chain kink by link, is one of the reasons that
    it is referred to as a 'chain'. If it was as simple as just a local
    object and a global object then the two could be described as 'the local
    scope' and the 'global scope', but the real mechanism is more complex
    than that.

    > That is why in time-crucial applications (say graphics
    > intensive ones) it is a good idea to use fully-qualified
    > path to window methods:


    You are about to put your foot in your mouth agian.

    > it saves the engine from searching and failing first in
    > the local scope. Depending on the complexity of the local
    > scope structure the productivity gain for looped calls can
    > be very noticeable.


    Pure bullshit! What you are referring to as a "fully-qualified path to
    window methods" is using the property accessor - window.alert - in place
    of the Identifier - alert -, for example. What you are failing to take
    into account is that the - window - in - window.allert - is an
    Identifier, and so will be resolved against the scope chain.

    To resolve the Identifier - alert - the engine will examine the object at
    the top of the scope chain to see if it (or an object on its prototype
    chain, if any) has a property named "alert". If we assume that that
    object has no "alert" property then the engine moves on to the next
    object on the scope chain and does the same test. The global object is
    the last object on any scope chain, so if we assume that no object higher
    up the chain had an "alert" property than the resolution of the
    Identifier ends when the "alert" property of the global object is found.

    If the property accessor - window.alert - is resolved the fist step will
    be resolving the Identifier - window -, which uses the same mechanism as
    the resolution of the Identifier - alert -. If we assume that no other
    object on the scope chain has a property named "window" then the process
    ends when the "window" property of the global object is found. So the
    resolution of the Identifier - window - will take almost exactly the same
    amount to time as the resolution of the Identifier - alert - (if we are
    using the same scope chain as with - alert -). However, resolving the
    property accessor - window.alert - is not over yet, as now the object
    referred to by value of the "window" property of the global object needs
    to be examined to see if it has a property named "alert".

    The logic of the mechanism says that property accessors referring to
    properties of the global object will take longer to resolve than
    Identifiers referring to properties of the global object. And you may
    recall that the list time you were corrected on this point you were shown
    code that demonstrated an empirical test where the results showed
    Identifier resolution to be faster property accessor resolution, even on
    Windows IE, where there is most reason to expect the outcome to the
    other.

    Th notion that "fully-qualified paths" are quicker is an old wives tail,
    that if it was ever true certainly is false with current browsers.

    > In some languages current object ...

    <snip - waffle>
    .... only one usable alternative.

    So may words, so little understanding.

    Richard.
     
    Richard Cornford, Oct 27, 2006
    #8
  9. VK wrote:

    [snip]

    > Still in more direct relation with difficulties which you are
    > experiencing is the distinction between CURRENT OBJECT and DEFAULT
    > OBJECT


    Can't you just use phrases similar to "the this operator value", "the
    object referred to by the this operator", or "scope chain"? They might
    be more verbose, but at least they mean something unambiguous.

    > and their semi non-orthodoxy implementation in JavaScript.


    Huh?

    > The current object is always pointed by [this] keyword. Picturally
    > (but unofficially) it could be said that [this] points to whoever
    > requested at this time to execute the current chunk of code. In your
    > sample SomeObj is the one who requested useDoSomething execution and
    > [this] points to SomeObj.


    A succinct (and accurate) description would be:

    The this operator refers to the penultimate member of a member
    expression, or, if there is no such member, to the global
    object. This behaviour can be overridden using the
    Function.prototype.apply and call methods, which specify the
    object directly.

    That is, in the expression,

    a.b.c()

    'b' is the penultimate member and the this operator will refer to that
    object. In the expression:

    f()

    there is no member expression at all, so the this operator will refer to
    the global object. Finally, with:

    f.call(o)

    the first argument to the call method specifies the object to use. If
    null or undefined, the this operator refers to the global object.
    Otherwise, it refers to the first argument (though see below).

    One should also note that the this operator always refers to an object.
    Given the object,

    var object = { property: 'value' };

    and the expression:

    object.property.charAt(0)

    one immediate observation is that property is not an object; it is a
    string value. In cases such as this, the value is temporarily converted
    to an object (a String object here because it's a String value), and
    evaluation of the rest of the expression continues from there.

    Similarly, if the first argument to the Function.prototype.apply or call
    methods is a value, that value is converted to an object.

    <aside>
    This is why values cannot take on properties: the object used in that
    process is only temporary and when the object is no longer needed, it
    and its properties cease to exist.
    </>

    > The default object is the object where the engine searches first for
    > requested properties (against of what it tries to resolve the given
    > identifier): if no other object was explicitly indicated.


    This is part of the reason why "default object" is dubious: there is no
    single object used for identifier resolution. The scope chain consists
    of numerous objects, each of which is examined in turn until the
    relevant property is located, or the end of the chain is reached.

    [snip]

    > That is why in time-crucial applications (say graphics intensive
    > ones) it is a good idea to use fully-qualified path to window
    > methods: it saves the engine from searching and failing first in the
    > local scope.


    Rubbish. If an identifier is used as the left-most member in a member
    expression, then the scope chain still needs to be searched to determine
    what value or object reference that identifier represents. Including a
    reference to the global object unnecessarily should actually result in a
    marginal decrease in performance as, once it's found, the property that
    follows must then be located - an extra step.

    [snip]

    > useDoSomething : function()
    > {
    > with (this) {
    > return doSomething();
    > }
    > }


    That would be an utterly stupid thing to do.

    [snip]

    > 1) If your object is a singleton (it is supposed to be only one
    > instance of this object in the whole execution context) you may want to
    > use the singleton name instead of [this] inside its methods.


    Why? Surely it's more reasonable to require that client code behaves itself.

    [snip]

    Mike
     
    Michael Winter, Oct 27, 2006
    #9
  10. VK Guest

    > I suggest that as some point _you_ try reading and _understanding_ them,
    > as bookmaking then is hardly a useful substitute.


    For what purpose? I already accepted the fact that in the whole world
    there are only 4-6 extremely carefully selected people able (by their
    outstanding mental capabilities) to understand JavaScript - or at least
    to come close to its understanding.
    The very nature of JavaScript - which is one of the most sophisticated
    creations of the human mind - eliminate any possibility to talk about
    it by using vernacular constructions. Therefore and hereafter a strong
    understanding is required in a special language particularly developed
    to express entities and processes in JavaScript language. Despite this
    special metaphysical language is primarily based on British English, a
    proper knowledge of its grammar and especially a proper knowledge of
    entities pointed by lexems of the said language require years of
    careful studies under strict supervision of the above mentioned people
    - if they decide that the mental capabilities of the challenger will
    ever let him/her to achieve any success in the future. Even after
    become fluent in that special language, the person is still nowhere to
    understand JavaScript. She's only making an important yet preliminary
    step towards the achievement. Namely she's getting ready to read the
    texts of the Books of ECMA - under the same strict supervision in order
    to ensure the proper understanding of all passages. If this second
    stage is passed successfully and the challenger escaped the regular
    risks to die of the boredom or a brains overheat - then she's finally
    conditionally acknowledged as able to understand JavaScript. The
    drawback is that on this stage a proper description of any JavaScript
    phenomenon by former challenger requires the use of the metaphysical
    language she learned before: that makes her speech (though crystal
    clear for anyone from the selected ones) hardly understandable for
    regular people.

    This way I'm not pretending to ever understand JavaScript and I'm
    afraid I'll never have a time to learn the language to talk about
    JavaScript.
    Sometimes (but very often) I'm just trying to answer a question if I
    see that more explanations expressed in that language OP gets - more
    confused it becomes.

    :)
     
    VK, Oct 27, 2006
    #10
  11. In article <>, VK
    <> writes

    <snip>
    >Despite this
    >special metaphysical language is primarily based on British English,


    So you can't understand "customise" because it doesn't end in -ize. Boy,
    have you got problems.


    <snip>
    >This way I'm not pretending to ever understand JavaScript and I'm
    >afraid I'll never have a time to learn the language to talk about
    >JavaScript.

    <snip>

    We had noticed.

    John
    --
    John Harris
     
    John G Harris, Oct 27, 2006
    #11
    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. Prakash Prabhu

    String literal and String Object

    Prakash Prabhu, Aug 27, 2003, in forum: Java
    Replies:
    3
    Views:
    655
    John C. Bollinger
    Aug 27, 2003
  2. BiraRai
    Replies:
    2
    Views:
    243
    BiraRai
    Oct 31, 2008
  3. mirirom

    Literal object definitions in asp.net

    mirirom, Jan 7, 2004, in forum: ASP .Net Web Controls
    Replies:
    3
    Views:
    215
    mirirom
    Jan 7, 2004
  4. Anonieko Ramos

    What's wrong with rpc-literal? Why use doc-literal?

    Anonieko Ramos, Sep 27, 2004, in forum: ASP .Net Web Services
    Replies:
    0
    Views:
    392
    Anonieko Ramos
    Sep 27, 2004
  5. Replies:
    2
    Views:
    158
    Robert Klemme
    Jun 7, 2006
Loading...

Share This Page