Unexpected scope question

Discussion in 'Javascript' started by risingfish, Feb 6, 2012.

  1. risingfish

    risingfish Guest

    Hello, I would call myself a fairly competent JavaScript programmer,
    but I ran into something expected today. Here's a snippet:

    NS.MyClass = function () {

    var initialize = function() {
    /* do something */
    NS.Instances[<uniqueId>] = this;


    var obj = new NS.MyClass();

    The object that ends up in NS.Instances[<uniqueId>] is DOMWindow, not
    the particular instance of that class. I can obviously fix it with
    call() but I've found a hole in my knowledge and am trying to
    understand. Could someone explain what is happening there?

    risingfish, Feb 6, 2012
    1. Advertisements

  2. The bigger question is why you've decided to write JavaScript in this
    manner. Why do you have an inner function in the first place?
    Michael Haufe (TNO), Feb 6, 2012
    1. Advertisements

  3. risingfish

    Scott Sauyet Guest

    From version 5.1 of the ECMA-262 spec (June, 2011) [1]:

    | 10.4.3 Entering Function Code
    | The following steps are performed when control enters the execution
    | context for function code contained in function object F, a caller
    | provided thisArg, and a caller provided argumentsList:
    | 1. If the function code is strict code, set the ThisBinding to
    | 2. Else if thisArg is null or undefined, set the ThisBinding to the
    | global object.
    | 3. Else if Type(thisArg) is not Object, set the ThisBinding to
    | ToObject(thisArg).
    | 4. Else set the ThisBinding to thisArg.
    | ...

    So, when you call `initialize` from within your constructor function
    without specifically binding `this`, the ThisBinding defaults to the
    global object.

    As you say, you can fix this with `call`:

    | initialize.call(this);

    You also might want to reconsider having the initialize function
    redefined for each call to the constructor by storing it in a local
    closure. Or, if it's as simple as what you've exposed here, remove
    the inner function altogether, as Michael suggests.

    -- Scott

    [1]: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
    Scott Sauyet, Feb 6, 2012
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.