0

I'm confused as to what the problem is with context in a JS constructor. Within the ctor I have a function declared. Before the call to that function this is set to the context of the ctor. Inside the function the value of this is set to window. I don't understand why. In the HTML the ctor is called with 'new'.

function MyCtor() {
    var myFunc = function() {
         debugger; // #2
         // code for myFunc
     }

     debugger;  // #1
     myFunc();
     debugger;  // #3
}

At debugger #1, this is set to MyCtor. At #2 this is window. And at #3 it is back to MyCtor.

I'm sure I'm missing something basic here, but I've read a lot on scope and context; obviously not enough.

6
  • 2
    Read about functions and scope here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Oct 10, 2013 at 21:18
  • …and about the this keyword ("context") here. It should never have been set to MyCtor, unless you're calling the constructor in weird ways. Commented Oct 10, 2013 at 21:29
  • @Bergi when we call MyCtor with new, what will the 'this' be displayed inside the body? Commented Oct 10, 2013 at 21:35
  • @grape_mao: The new instance (an object inheriting from MyCtor.prototype). developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Oct 10, 2013 at 21:36
  • @Bergi sure, but in the console it shows somwthing like 'MyCtor{}'. Maybe that's why OP says this is set to MyCtor. Commented Oct 10, 2013 at 21:43

1 Answer 1

2

The this object is one of the most annoyingly hard-to-understand concepts in Javascript. And that's quite a contest to win... First off, you have to understand that it will be specific to each function you call - the context in which you call myFunc won't set it how you want it. Here's one way you can do it:

function MyCtor() {
    this.myFunc = function() {
         debugger; // #2
         // code for myFunc
     }

     debugger;  // #1
     this.myFunc();
     debugger;  // #3
}

Generally, there are only a few situations in which you can rely upon a function's this to be a particular value. All of them to my knowledge:

objectToBeThis.aFunction = function() { ... } // declare this function as
// an object property at any time - 
objectToBeThis.aFunction();

Or, not used as often is:

aFunction.call(objectToBeThis, extraArgument1, extraArgument2);

When a named, but not "owned" function (ie, var functionName = function(), or function functionName()) is called, then it will have window as its this argument. This part I'm less sure of as a certainty, but I just wouldn't use this inside such a method.

As in the case of your code, there's also "new MyCtor" - in which a new object is created to be returned, and that object is set to this inside of the constructor method.

Sign up to request clarification or add additional context in comments.

3 Comments

Still a bit confused here. Does this mean that via hoisting, all 'var' declarations really belong to 'window'? I would think that that would lead to name collisions. If myFunc is declared within the constructor using 'var', why isn't it bound to MyCtor?
Found additional info in (stackoverflow.com/questions/8670877/…)
Anything that belongs to 'window' is a global. Any function arguments, or variables declared inside of a function, are local variables accessible to that function, as well as any functions declared inside that function (closures). vars don't really "belong" to any object, and as such, you don't use the dot syntax for them. This also means you can't access a var outside of the function it was declared in. Hope that helps; it's definitely confusing.

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.