0
A(); // prints 'a'

function A() { console.log('a'); }
function B() {
    function C() { console.log('c'); }
    function D() { console.log('d'); }
    console.log('b');
}

How do I call function C or D from outside of B without changing the contents of function B durastically?

For example, I don't want to change B() to be like this:

function B(arg)
{
 function C() { console.log('c'); }
 function D() { console.log('d'); }

 if (arg == 'C')
  C();
 if (arg == 'D')
  D();

 console.log('b');
}
6
  • Any reason why you don't want to modify B()? Commented Aug 27, 2014 at 2:43
  • Because I need to be able to call B() without arguments, I don't want to have to specify arguments to B() each time. C() and D() need to be inside B() for convenience. Commented Aug 27, 2014 at 2:43
  • 1
    If you define functions to be within a particular scope, you can't access them outside that scope. If you could, it would entirely defeat the purpose of variable scope. Commented Aug 27, 2014 at 2:44
  • You don't have to specify arguments to B even after the modification. It's just that if you don't pass anything in, C and D will not be called. Commented Aug 27, 2014 at 2:45
  • Function declarations and variables (via var) have the same scope - the identifier is bound to the enlcosing function block. Generally an aggregate group of functions is exposed via properties of a returned objects. Commented Aug 27, 2014 at 2:46

5 Answers 5

2

C() and D() are local functions that are private to the scope of B(). They are like local variables. They only exist within the scope of B(). That is how the scoping in Javascript works.

You cannot access them outside of B() unless you pass references to them to other functions, return them from the function or you change the structure so they are declared or assigned to to a higher level scope rather than inside of B().


For example, you can pass a reference to them to another function:

function B() {
    function C() { console.log('c'); }
    function D() { console.log('d'); }
    console.log('b');
    setTimeout(C, 1000);
}

Then, when you call B(), it will first output b and then 1 second later it will output c.


Or, you could change their structure by making those functions be properties of the B function object:

function B() {
    B.C = function() { console.log('c'); }
    B.D = function() { console.log('d'); }
    console.log('b');
}

Then, you can call B() or to get access to C or D, you call them like B.C().


Or, you could return an object from B() that had both functions on it:

function B() {
    var obj = {};
    obj.C = function() { console.log('c'); }
    obj.D = function() { console.log('d'); }
    return obj;
}

var functions = B();
functions.C();

Or, you can make B() be a constructor function:

function B() {
    this.c = function() { console.log('c'); }
    this.d = function() { console.log('d'); }
    return obj;
}

var obj = new B();
obj.c();

FYI, a regular convention in Javascript is that constructor functions start with a capital letter and other functions/methods start with a lowercase letter.

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

Comments

1

As per javascript scope you cant access them from outside B().

You will have to modify B() in order to be able to access them.

Comments

0

You have B() setup for use as a constructor. If you want to access the inner functions of B(), you need to create a new instance of it with the new keyword. However, C() and D() are private functions. We can change them public functions like this:

function B() {
    console.log('b');
    this.C = function() { console.log('c'); } //public function
    function D() { console.log('d'); } //private function (no this keyword)
}

You then have to create an instance of B() to access its public values.

var b = new B(); //logs 'b'
b.C(); //logs 'c'
b.D(); //throws an error because D() is private

Comments

0

It is impossible to access C or D from outside B. Here's some alternative options:

function A() { console.log('a'); }
function B() {
    function C() { console.log('c'); }
    function D() { console.log('d'); }
    return {
       C: C,
       D: D
    };
}

B().C();
B().D();

or

var C, D;
function A() { console.log('a'); }
function B() {
    C = function() { console.log('c'); }
    D = function() { console.log('d'); }
}
B();
C();
D();

Comments

0

I am guessing you are looking for a way to pass argument to B without modifying it right ? ? so how about this ..

function ABC(arg){
 function B()
 {
  function C() { console.log('c'); }
  function D() { console.log('d'); }

  if (arg == 'C')
   C();
  if (arg == 'D')
   D();

  console.log('b');
 }

 B();
}

I am guessing that you are looking for a solution in this line.

Comments

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.