5

The following javascript code, allows you to access the global object (window/worker).

(new function Outer(){
    console.log(this); /* The object */
    (function(){ // This function could be a 3rd Party function 
        console.log(this); /* window !!*/
    })();
});

Is there a way by which I can ensure that the inner this always gets a reference to Outer's context.

I know i can do

(new function Outer(){
    'use strict';
    console.log(this); /* The object */
    (function(){ // This function could be a 3rd Party function 
        console.log(this); /* undefined ? !!*/
    })();
});

but that results in this being undefined.

Edit

I know about bind, but what if the inner function is nested. for instance something like

(function(){

    (function(){
        (function(){
           console.log(this);// undefined
        })();

    })();

}).bind(this)();

What i want is : Outer {} and not a reference to the outer using a variable :-|

3
  • 1
    So you don't want window, but you also don't want undefined. Hate to break it to you, but those are the two defaults that will be used for functions that are invoked without any other indicator of the this value. Commented Nov 25, 2013 at 21:29
  • Thats why i asked, wondering if there exists a trick to not have either.. But i guess i will have to be satisfied with undefined Commented Nov 25, 2013 at 21:33
  • Nope, no trick. I'm not sure what the value would be if it wasn't either of those. ECMAScript 6 will have functions with a lexical this, but that's of little use today, and it's only for functions with the new syntax. Commented Nov 25, 2013 at 21:34

3 Answers 3

7

You can use function.call.

new function Outer(){
    'use strict';
    console.log(this); 
    (function(){ // This function could be a 3rd Party function 
        console.log(this);  //<-- Now it will it the one from the outer scope
    }).call(this);
}; // You don't need to invoke this explicitly here with () since you are invoking it already with new keyword so constructor invocation doesnt need ()

Or a best bet would be to cache the context outside and use it anywhere in the inner scope.

new function Outer(){
        'use strict';
        var self = this;
        console.log(this); 
        (function(){ // This function could be a 3rd Party function 
            console.log(self);  //<-- Now it will it the one from the outer scope
        })();
 };
Sign up to request clarification or add additional context in comments.

11 Comments

What if the inner function is nested a few level in ?
I think you meant .bind(this)(), but +1 for doing the right thing. (Also you could use .call(this) and have it work way back :-)
@AbhishekHingnikar The other solution is to store a reference to the outer this inside another variable, like var that = this and then use that to refer to the outer this variable. However, that requires you to edit the code of the inner function.
@SeanVieira yeah i meant call... :) Good catch
I know it was from the code in the question, but the final trailing () shouldn't be there since the Outer function is invoked with new. You can also get rid of the wrapping ().Just new function Outer() {...}; is enough.
|
1

You can use a closure variable:

(new function Outer(){
    'use strict';
    console.log(this);
    var me = this;
    (function(){
        console.log(me);
    })();
})();

Comments

1

This trick simply stores the "outer" this inside a variable that you can access from inner functions (and inner-inner function and so on).

In some cases, this can be useful because you have access to both the inner this (if there is a context for it) and the outer this.

(new function Outer(){
    'use strict';
    console.log(this); /* The object */
    var _this = this;
    (function(){ // This function could be a 3rd Party function 
        console.log(_this); /* The outer object */
    })();
})();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.