|The this problem|
Page 2 of 2
First let's look at the constructor again:
The first use of this is immediate, i.e. it is evaluated within the constructor, and when the constructor exists the this reference isn't used again. The second use of this is deferred as it is used within a function definition.That is within any instance the show function actually reads alert(this.message) and so what this means depends on what it is set to i.e. the context of the method call. You can check this assertion using
when the functions code will be displayed and you will see this within the instructions.
You can think of this as using the this value at the time the constructor is executed or using the this value at the time the method is executed.
Normally when you call a method as in
this is set to the context of the call i.e. the object that the call is made on - in this case this=myObject1 and so when the code this.message in show() executes it assesses myObject1.message.
What this all means is that the within the instances method references to the instances variables are not fully resolved even though the method is stored within the instance. This is a little odd from a pure object oriented point of view and it would be simpler if the constructor replace instance variable references with full worked out references. That is rather than store this.message within the method's code it would be better if it stored myObject.message i.e. if it evaluated the this at the time the function was constructed.
You should now be perfectly clear why
doesn't work. The problem is that when methodpointer calls myObject1.show this isn't set to myObject but to the global object or to what ever object methodpointer belongs to. In this case you get an undefined error because there is no message variable defined at the global level.
How to avoid this one is a difficult question.
The standard way of providing context to methods so that they work even then this is incorrectly set it so save a copy of this at the time of construction.
Notice that this is stored in a local variable self and it is self that is used within methods whereever this would have been use. Now when you try
it calls myObject1.show because the context of the method call is being provided by self which was set when the constructor was called and not by this at the time the method was called.
Notice that this solution is slightly more sophisticated than you might give it credit for. Why, for example, is self defined as a local variable? Also how can the method access self when it is local to the constructor which finished running some time ago? (Recall local variables are destroyed when a function ends.) The answer is that show has access to self because a closure is formed preserving all of the constructors local variables when it terminates.
The fact that a closure is used to store the value of this at the time the constructor ran is the problem with the method. The object created by the constructor can be extended in ways that do not benefit from the closure and this means that the self variable isn't accessible from all of the objects methods. More of this in another puzzle.