简体   繁体   中英

JavaScript Accessing Functions within functions

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');
}

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 BC() .


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.

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.

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

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();

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM