12

I am having a JavaScript namespace say

A={

  CA: function() {
    this.B();
  },
  B: function() {
    var test='test';
    var result='t1';

    C: function() {
      this.test='test1';
      .....
      .....
      return 'test1';    
    }

   result=this.C();  
   return result; 
  }
}

Now when I am executing such code it is giving that TypeError: this.C is not a function. Can somebody tell me why it is so. I know it is something related with lexical scoping but am unable to understand this.

pbialy
  • 1,025
  • 14
  • 26
Ashish Jain
  • 4,667
  • 6
  • 30
  • 35
  • Sorry, I am a new user and posted the first question, don't know how to post questions. I will keep this in mind now onwards. Thanks. – Ashish Jain Jul 07 '09 at 14:48

4 Answers4

30

You have to be careful when you use this to identify anything in Javascript because each time you change scope "this" changes.

Assigning the 'this' reference to it's own variable helps get around this.

var a = new function() {
    var self = this;

    self.method = function() { alert('hiya'); };

    var b = function() {
        this.method(); // this isn't 'a' anymore?
        self.method(); // but 'self' is still referring to 'a'
    };

};
hugoware
  • 35,731
  • 24
  • 60
  • 70
5

I think the problem is that when this.C() is executed inside the function referred to by B, this refers to the object that contains B, that is, object A. (This assumes B() is called within the context of A)

The problem is, C does not exist on the object A, since it's defined within B. If you want to call a local function C() within B, just use C().

EDIT: Also, I'm not sure what you've posted is valid JavaScript. Specifically, B should be defined this way, since you can't use the object:property syntax within a function.

B: function()
{
  var test='test';
  var result='t1';

  var C = function()
  {
    this.test='test1';
    return 'test1';    
  }

 result=C();  
 return result; 
}
Peter
  • 6,354
  • 1
  • 31
  • 29
  • I think you are correct and I also did the same way finally (made the function and called it directly from the outer function) after banging my head to make this.C working. – Ashish Jain Jul 07 '09 at 14:39
4

I am actually surprised that your code doesn't give you error on the 'C:' line.

Anyway, your syntax to define a function is not correct. Define it using the var keyword. Also, notice that I created the 'closure' so that the function C can access 'this'. See the code below:

A={

  CA: function()
  {
    this.B();
  },

  B: function()
  {
    var test='test';
    var result='t1';

    var self = this;
    var C = function()
            {
              self.test='test1';
              .....
              .....
              return 'test1';    
            }

   result=C();
   return result; 
  }
}

If you want to assign C to 'this' object, you can also do:

A={

  CA: function()
  {
    this.B();
  },

  B: function()
  {
    var test='test';
    var result='t1';

    var self = this;
    this.C = function()
             {
              self.test='test1';
              .....
              .....
              return 'test1';    
             };

   result= this.C();
   return result; 
  }
}
SolutionYogi
  • 31,807
  • 12
  • 70
  • 78
  • You won't be able to use 'this' because 'this' is a keyword and you do need to create the closure. Also, because I am defining the 'self' as a local variable, it won't impact the global object. – SolutionYogi Jul 07 '09 at 14:33
  • yeah sorry, I realised my dumbness, and hence deleted my comment :-( But Yes now i agree with your answer. +1 for putting up with me too :-) – Dave Archer Jul 07 '09 at 14:34
2

Solution for calling methods from another method. (Essentially the pointer "this" must be assigned to a variable and the new variable used in place of this.)

 function myfunction(){
    var me = this;

    me.method1 = function(msg){ alert(msg); }

    me.method2 = function(){ 
       me.method1("method1 called from method2"); 
    }
 }

 var f as new myfunction();
 f.method2();

This example shows how one can call a method from within another method or from outside using an instance of the function.

Rex
  • 357
  • 3
  • 5