Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between returning a function and using function.innerFunction?

Its a general question about something i seem to encounter a lot: When should i use

function Bla(){return function(){alert("bla");}}

and call the main function Bla, and when should I use

function Bla(){function innerBla(){alert("bla");}}

and call Bla.innerBla?

What is the difference between them?

like image 498
ilyo Avatar asked Feb 24 '23 02:02

ilyo


1 Answers

Those are two different ways of doing things, and they operate differently.

The first one is a function that returns another function. Thus, to invoke the inner function, you need to first call the outer one, Bla, (which returns the inner one) and then invoke the returned value (the inner function):

function Bla(){
    return function(){
      alert("bla");
    }
}

Bla()(); // will alert "bla"

The second one just defines an inner function, and there's no way of invoking that inner function from outside of the outer function because it's scoped only within the outer function Bla:

function Bla(){
    function innerBla () {
      alert("bla");
    }
}

Bla(); // will do 'nothing'

Bla.innerBla is undefined because the object (functions are objects in JavaScript) Bla does not have a member called innerBla attached to it.


If you want to invoke it like bla.innerBla, you should do something like this:

function bla () { /* */ }

bla.innerBla = function () {
    alert("bla");
};

bla.innerBla(); 
// will alert "bla" because the `bla` object now has a member called `innerBla`.

Or you can have something like this (a pattern that I frequently use):

function bla () {
    return {
        innerBla: function () {
            alert("bla");
        }
    };
}

bla().innerBla(); // will also alert "bla"

If you want to use the constructor pattern (new), you need to do something like this:

var bla = function () {
  this.innerBla = function () {
    alert("bla");
  };
};

var b = new bla();
b.innerBla();

This is equivalent to having a public property on an instance of an object in an OO language.


And finally, if you want to expose innerBla by every 'instance' (achieved using a constructor i.e. invoking bla using the new keyword) of bla, you should add the function to bar.prototype.innerBla:

var bla = function () { /* */ };
bla.prototype.innerBla = function () {
  alert("bla");
};

var b1 = new bla(), 
    b2 = new bla();

b1.innerBla(); // will alert "bla"
b2.innerBla(); // will also alert "bla"

This is similar to having a static method.


On a side note, avoid naming functions with an initial capital case letter (pascal-case) because by convention, usually we only capitalize functions which need to be invoked using the new keyword (constructors).

like image 76
Andreas Grech Avatar answered Apr 27 '23 16:04

Andreas Grech