1

I am new to js and felt that I understood the concept of this until I came across.

        function TopLevelFn(){
            var obj = {
                empId : 232
            };
            console.log('TopLevelFn() empId :' + obj.empId);
            innerFn();

            function innerFn(){
               //why this points to window object...
                console.log('innerFn() empId :' + this.obj.empId); 

            }
        }

        var register = new TopLevelFn();

If I understood it clearly the innerFn() is called from TopLevelFn() so the invoking obj and this should be ref to TopLevelFn()?

tintin
  • 5,676
  • 15
  • 68
  • 97
  • Context depends on how you invoke the function. – dfsq Nov 14 '14 at 11:05
  • http://stackoverflow.com/questions/111102/how-do-javascript-closures-work – rjdmello Nov 14 '14 at 11:05
  • Thanks, but that doesn't explain this scenario to me. this should be having the obj in its context because its invoked from the enclosing fn. – tintin Nov 14 '14 at 11:20
  • No it should not. You misunderstand. Just because the function is within another function doesn't mean anything. Context is determined by how you invoke the function. – dfsq Nov 14 '14 at 11:21

1 Answers1

0

Context depends on how you invoke the function. Your case is described in ECMAScript spec 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 thisArg.
  2. Else if thisArg is null or undefined, set the ThisBinding to the global object.

Since you don't provide a thisArg the function is executed in global context.

Now you may ask how to provide thisArg value? ECMAScript defines three methods to explicitly specify execution context: Function.prototype.call, Function.prototype.apply and Function.prototype.bind (returns new function). In your case you can use call like this:

innerFn.call(this);

in this case innerFn will be invoked in context of this object. Otherwise innerFn() will have global context.

dfsq
  • 191,768
  • 25
  • 236
  • 258