Assigning methods to objects, and assigning onreadystatechange to an XMLHttpRequest -- an inconsiste

Discussion in 'Javascript' started by weston, Sep 22, 2006.

  1. weston

    weston Guest

    So, the following apparently works as a method of grafting a method
    onto an object (using the squarefree JS shell):

    obj = { x: 1, inc: null }
    result> [object Object]
    obj.inc = function () { this.x++ }
    result> function () { this.x++; }
    obj.inc()
    obj.x
    result> 2

    And by works, I mean that when I create an object, and then assign one
    of its properties an anonymous function, the "this" keyword within said
    anyonymous function apparently refers to the object itself. Convenient.
    I like it.

    The problem is, in the context of an XMLHttpRequest object, this
    doesn't seem to work as well for me. Again, using the squarefree js
    shell:

    xhr = new XMLHttpRequest()
    result> [object XMLHttpRequest]
    xhr.onreadystatechange = function () { alert(this.responseText); }
    result> function () { alert(this.responseText); }
    xhr.open("GET","http://www.squarefree.com/shell/shell.html",true)

    Now, one might think this would produce an alert containing the
    text/html of shell.html. But it doesn't. The value of this.responseText
    is apparently undefined.

    A slight variation reveals an apparent explanation:

    xhr.onreadystatechange = function () { alert(this); }
    result> function () { alert(this); }
    xhr.open("GET","http://www.squarefree.com/shell/shell.html",true)

    This produces an alert that ... displays the code of the anonymous
    function itself.

    So, apparently, in this case, the "this" keyword refers to the function
    itself, and it would seem I can't graft-on methods that have access to
    the other properties of the XMLHttpRequest object. At least via the
    "this" keyword.

    Can someone help me understand what the differences between the two
    situations are?

    Also... the reason why I'm interested in this largely has to do with
    some vague stylistic discomfort. Much of the code I've seen and written
    using XMLHttpRequests uses global / lexically scoped variables to get
    information across curly-braces between functions. If I could graft
    methods onto the request objects themselves, I think I could cut down
    on this. I'm open to other suggestions.
    weston, Sep 22, 2006
    #1
    1. Advertising

  2. weston wrote:
    > So, the following apparently works as a method of grafting a method
    > onto an object (using the squarefree JS shell):
    >
    > obj = { x: 1, inc: null }
    > result> [object Object]
    > obj.inc = function () { this.x++ }
    > result> function () { this.x++; }
    > obj.inc()
    > obj.x
    > result> 2
    >
    > And by works, I mean that when I create an object, and then
    > assign one of its properties an anonymous function, the
    > "this" keyword within said anyonymous function apparently
    > refers to the object itself. Convenient. I like it.


    As expressed, that effect is an illusion as - this - is determined
    always, and only, by how a function is called. If you call one as a
    method of an object, as you do above, - this - will refer to that
    object.

    > The problem is, in the context of an XMLHttpRequest object,
    > this doesn't seem to work as well for me. Again, using the
    > squarefree js shell:
    >
    > xhr = new XMLHttpRequest()
    > result> [object XMLHttpRequest]
    > xhr.onreadystatechange = function () { alert(this.responseText); }
    > result> function () { alert(this.responseText); }
    > xhr.open("GET","http://www.squarefree.com/shell/shell.html",true)
    >
    > Now, one might think this would produce an alert containing
    > the text/html of shell.html. But it doesn't. The value of
    > this.responseText is apparently undefined.


    The problem is that you don't know how the onreadystatechange handler is
    being called by the browser so you cannot know in advance what - this -
    will refer to. Experimentation reveals that (for IE at least) it is not
    called as a method or any particular object.

    > A slight variation reveals an apparent explanation:
    >
    > xhr.onreadystatechange = function () { alert(this); }
    > result> function () { alert(this); }
    > xhr.open("GET","http://www.squarefree.com/shell/shell.html",true)
    >
    > This produces an alert that ... displays the code of the
    > anonymous function itself.


    I bet that is not universally true.

    > So, apparently, in this case, the "this" keyword refers
    > to the function itself, and it would seem I can't
    > graft-on methods that have access to the other
    > properties of the XMLHttpRequest object. At least
    > via the "this" keyword.


    Yes, you cannot use - this - practically, so you must provide access to
    objects of interest by some other means (and there are plenty of
    options).

    > Can someone help me understand what the differences
    > between the two situations are?


    The difference is between knowing how a function is being called and not
    knowing. Generally when you don't know you can work it out by trying,
    but if the results are not useful you still have to deal with that.

    > Also... the reason why I'm interested in this largely
    > has to do with some vague stylistic discomfort. Much of
    > the code I've seen and written using XMLHttpRequests
    > uses global / lexically scoped variables to get information


    Globals are not so good, as multiple asynchronous requests will tend to
    overwrite them. Exploiting closures (the lexically scoped stuff) is much
    better.

    > across curly-braces between functions.
    > If I could graft methods onto the request objects
    > themselves, I think I could cut down on this. I'm
    > open to other suggestions.


    That is quite an 'if' as there is no reason to expect that the request
    object can have properties added to it at runtime (except that that is
    common in javascript environments) as they are host objects and may not
    provide the facility.

    Bus since you cannot get - this - to reliably refer to the request
    object the question is academic.

    Richard.
    Richard Cornford, Sep 22, 2006
    #2
    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. Replies:
    2
    Views:
    221
  2. Replies:
    2
    Views:
    190
    Benjamin
    Sep 14, 2006
  3. Peter Michaux
    Replies:
    2
    Views:
    168
    Peter Michaux
    Oct 28, 2006
  4. Replies:
    4
    Views:
    476
  5. HugeBob
    Replies:
    10
    Views:
    279
    HugeBob
    Apr 6, 2007
Loading...

Share This Page