LED Fantom
LED Fantom

Reputation: 1373

Confusion of calling a Javascript function

Could someone explains why "myPet = pet(Vivie);" does not actually call the pet function, but myPet() does? It's different from the programming languages I learned like Java. Thanks.

var pet = function(name) {                
  var getName = function() {    
    return console.log(name);               
  } 
  return getName;                   
},

myPet = pet("Vivie"); // ????????
myPet(); // Returns "Vivie"

Upvotes: 1

Views: 152

Answers (9)

Md Ashaduzzaman
Md Ashaduzzaman

Reputation: 4038

In javascript functions are treated as DATA. So you are permitted to use functions as variable.

In the following line,

myPet = pet("Vivie");

what you are actually doing is calling the pet function, wrapping up the returned function and putting it inside myPet.

But when you code this,

myPet();

you are calling myPet() function[the returned function from pet]. And this is the exact myPet that you got after you assigned pet into it.

That is the reason when you code myPet(); it's invoking the function.

Now Here's an interesting thing,

When you code this,

var pet = function(name) {                
  return console.log(name);                 
},

myPet = pet("Vivie");

it works!!!! Why its working then???

Here when you you are calling the pet function it consoles your name and returns the console. It's not returning any function.

But in your code in myPet you are getting a function.

Lets test what we understand seeing the type of the returned object from pet,

In your case :

var pet = function(name) {                
  var getName = function() {    
    return console.log(name);               
  } 
  return getName;                   
}

var myPet = pet("Vivie");
console.log(typeof myPet); // consoles : function.

You are calling the pet, but you are not executing anything inside that returned function. Rather you are saying that you can execute this returned function using myPet.

Another Case :

var pet = function(name) {                
  return console.log(name);                 
}

var myPet = pet("Vivie");  // consoles : Vivie
console.log(typeof myPet); // consoles : undefined

First you are executing pet and return the console which is why when you ask for typeof myPet you don't get any defined type.

And finally if you want to invoke the returned function immediately then you should go with the self-invoking function this way.

myPet = pet("Vivie")();

Moral of the story :

myPet = pet("Vivie");

Here myPet refer to pet. And

myPet();

here myPet invokes pet.

References : typeof

Upvotes: 1

slevy1
slevy1

Reputation: 3820

If you come from a language that does not support first class functions, then it can be confusing when you encounter one that does. A first class function is one that can be passed to a function or returned from a function just as if it were ordinary data like a string or a number. The following code should shed some light:

var pet = function(name) {   // assign anonymous func to pet               
  var getName = function() { // assign nested anonymous func to getName
    console.log(name);       // prints to console; no return value               
  };
  return getName;            // return getName value: func definition   
};

myPet = pet("Vivie");        // assign getName value to myPet 
myPet();                     // appending () invokes defined func

"Vivie" gets passed to the function that pet holds, yet console.log() prints it! This is accomplished by a feature known as a closure. Since name exists in the nested function's immediate external environment, the variable binds to it and continues to exist even after the outer function (contained in pet) executes.

Aboutconsole.log(), note it is incorrect to write it as part of a return statement because the logging method never returns a value; it just prints to the console. So with the following code:

var pet = function(name) {                
  var getName = function() {    
    return console.log(name);               
  } 
  return getName;                   
},

myPet = pet("Vivie"); 
console.log(typeof myPet());  

in the last statement, myPet() executes causing "Vivie" to be printed to the console but it returns nothing. So, typeof returns "undefined" and that result, too, gets printed to the console. See http://jsfiddle.net/yu75k5tz/.

Returning to the main topic of passing a function, consider the previous snippet again. There is an alternate and more economical way to achieve the same result by using function call chaining, as follows:

pet("Vivie")();

The first set of parentheses invokes pet which returns a function, albeit anonymous. The second pair of parentheses cause the returned function to execute. This code eliminates having to assign getName to a variable, which in turn reduces two statements to this one-liner.

Finally, the trailing semi-colons of the function definitions may appear odd but they are syntactically correct. Each anonymous function is being assigned to a variable, so each of these semi-colons actually terminates an assignment statement.

Live demo here: http://jsfiddle.net/kLghedp3/8/

Upvotes: 1

Mritunjay
Mritunjay

Reputation: 25892

If You will execute code in console one by one, you will get the answer probably.

myPet = pet("Vivie");

The above line is assigning a function to myPet which h a body like bellow

function () {    
    return console.log(name); 
  }

here value of name is coming from closure of pet function.

when you are calling myPet it's calling that function with the name as Vivie.

So if you are worrying that you function pet is not calling the method, that is because in pet function no-where the function has been called. It's just returning the function definition itself.

If you want pet function to print retsult, define it like bellow

var pet = function(name) {                
  var getName = function() {    
    return console.log(name);               
  } 
  return getName();                   
}

Upvotes: 0

Md. Arafat Al Mahmud
Md. Arafat Al Mahmud

Reputation: 3214

Why do you think that myPet = pet("Vivie"); doesn't call the pet function ? pet is obviously called and returns a new function which is assigned to myPet.

Now back to your code.

myPet = pet("Vivie"); // ????????

Well, it won't print anything. It just returns another function. This is called currying. You can learn more about currying here

myPet(); // Returns "Vivie"

Reason why it returns "Vivie" is because pet formed a closure and the returned getName function is in its scope. So getName can see and capture the value of pet's argument(In this case "Vivie") and retain it. What myPet() does is actually invoking the definition of getName. You can learn more about closures here

Upvotes: 0

Amer
Amer

Reputation: 419

This is the difference between js functions and variable functions, following is the very good explanation of these

JS Functions Vs Variable Functions

you can call this function directly by modifying your code like:

    var pet = function(name) {                

    return console.log(name);               

};

pet("test1"); 

Upvotes: 0

Carlo Gonzales
Carlo Gonzales

Reputation: 365

What you did when you called pet was return a function and set the string "Vivie" on the function-scoped variable name. So, your myPet variable recieves the getName value, a function printing the value of the function-scoped name variable. By the time you called myPet, you were already invoking the function returned by pet, which is getName printing the name variable with a preset value of "Vivie".

Hope that helps clear it. :)

Upvotes: 0

Khaleel
Khaleel

Reputation: 1371

By this line myPet = pet("Vivie"); you are assigning a function along with a parameter to the var myPet. So myPet will become another function as

var getName = function() {    
 console.log(name);               
  } 

Hence you have to call myPet(); as a function to get return.

Upvotes: 0

Tushar Gupta
Tushar Gupta

Reputation: 15923

The pet() returns the function and assigns it to your variable myPet. So Mypet() actually calls the function. If you want to call the function that pet() returns you can also do: pet("some name")();

You can try editing the following example for better understanding:

If you comment out myPet = pet("Tushar");the code wont run because mypet() has not been assigned anything. Try it.

var pet = function(name) {                
  alert(name);                   
},

myPet = pet("Tushar"); 
myPet(); 

Upvotes: 0

Eudis Duran
Eudis Duran

Reputation: 782

pet() returns the function and assigns it to myPet. If you want to call the function that pet() returns you can also do: pet('Vivie')();

Upvotes: 0

Related Questions