0

i have this two functions, inside one function.

var funcA = function(){
  var funcB = function(){
    // function codes
    funcC();
  }

  var funcC = function(){
    // function codes
    funcB();
  }
}

funcA is executed first, then when I call funcB it produce error Object [object global] has no method 'funcC'. if i put funcC right before funcB the error is now pointing to undefined funcB.

how to fix this problem?

Dariel Pratama
  • 1,607
  • 3
  • 18
  • 49
  • 6
    Calling funCC() in funcB() and vice versa. Won't it yield infinite loop? – malkam May 14 '14 at 07:27
  • 1
    Your example has a couple of problems making it hard to see what the actual problem might be. First, if you execute funcA there would be no way to execute funcB and funcC as they would be hidden in the scope of funcA. Second what you have would lead to an infinite recursive loop if you called funcB or funcC – rom99 May 14 '14 at 07:30
  • thanks @malkam for pointing this to me, what i trying to do is when calling `funcB` it is also execute scripts at `funcC` vice versa. – Dariel Pratama May 14 '14 at 07:35
  • How are you calling the function? – bozdoz May 14 '14 at 07:43
  • @bozdoz `funcA` is call in `onclick`. inside funcA there is event listener that will make funcB get triggered when event is captured. – Dariel Pratama May 14 '14 at 07:50

3 Answers3

1

Your problem is in the way you're declaring functions:

var funcB = function(){
    // function codes
    funcC();
  }

var funcC = function(){
    // function codes
    funcB();
}

When you're declaring funcB, it tries to find funcC, which doesn't exist, yet. This breaks your code, throwing an undefined error.

You can define the functions like this:

function funcB(){
    // function codes
    funcC();
  }

function funcC(){
    // function codes
    funcB();
}

However, if funcB calls funcC, and funcC calls funcB, it doesn't matter how they're declared / initialized, you're going to have an infinite loop, probably resulting in a stack overflow-like error, or a crashing browser (/tab).

Chrome throws this:

RangeError: Maximum call stack size exceeded

To avoid that error, do something like this:

function funcB(calledFromC){
    if(!calledFromC){
        funcC(true);
    }
}

function funcC(calledFromB){
    if(!calledFromB){
        funcB(true);
    }
}

Or shorter:

function funcC(calledFromB){
    !calledFromB && funcB(true);
}
Cerbrus
  • 70,800
  • 18
  • 132
  • 147
  • This is true only if `funcB` is called before `funcC` is defined, which I don't think OP meant to do, since it's wrapped in another function. – bozdoz May 14 '14 at 07:33
1

If you would declare functions like this:

var funcA = function(){
   function funcB() {
      funcC();
   }

   function funcC {
      funcB();
   }
}

it would work. Why you ask? Read more about hoisting, scoping, function declarations and function expression here

check fiddle here

of-course it would be an infinite loop, so don't do this, but it would be correct javascript.

edit: if you would like to call them out of the scope (outside of funcA), you need to return them:

 var funcA = (function() {
    var funcB = function () {
        //code here
    };
    var funcC = function () {
        //code here
    };
    return {
        funcB: funcB,
        funcC: funcC
    };
   })();

Now you can do this outside the funcA:

funcA.funcB();
funcA.funcC();
avidenic
  • 653
  • 7
  • 17
  • Doesn't need to do it like this. Could do this.funcB and this.funcC and then do `var fA = new funcA; fA.funcB();` etc. Or do an object literal: `var funcA = { funcB : function () {} };`. – bozdoz May 14 '14 at 07:41
  • Yes ofcourse, he could do this.FuncA = function () {}; – avidenic May 14 '14 at 07:43
  • On your edit: function A should be fired anonymously or fired and then stored in a variable, this does not work otherwise. See fiddle: http://jsfiddle.net/SsmDG/1/ – Rick Lancee May 14 '14 at 07:45
  • yeah ofcourse, you are correct. Will correct the answer. – avidenic May 14 '14 at 07:47
  • I like the second option using a closure @RickLancee. – bozdoz May 14 '14 at 07:48
  • @bozdoz is it officially called a closure? I'm not that familliar with javascript terminology. – Rick Lancee May 14 '14 at 07:50
  • Pretty sure. It uses local variables instead of populating global variables. I think that's what is called a closure. I'm only just recently learning about them myself @RickLancee – bozdoz May 14 '14 at 08:26
0

You are probably asking the wrong question as interlinked methods rarely end happily.

The answer to your question really is because of this earlier answer regarding when functions actually exist. In particular read about function hoisting.

var funcA = function() {

  function funcB(){
    // function codes
    funcC();
  }

  function funcC() {
    // function codes
    funcB();
  }
}

funcA.funcB();
Community
  • 1
  • 1
vogomatix
  • 4,856
  • 2
  • 23
  • 46
  • Still looks wrong, but more correct. Should just remove `funcC();` and `funcB();` as they don't really make sense. – bozdoz May 14 '14 at 07:31
  • Haven't finished answer - must give up my bad habit of posting partial answers :-) – vogomatix May 14 '14 at 07:32