I expect this code to print undefined, but it prints function instead. Can anyone tell me why? I am new in JS.
function createGreeter(greeting){
function greet(){
console.log(greeting,name)
}
return greet
}
let g1=createGreeter('Good Morning')
console.log(typeof g1)
let g2=createGreeter('Good Evening')
So it looks like you want to create a function that accepts a greeting but returns another function that accepts a name (while maintaining a pointer to the variable (greeting) in its outer lexical environment when its returned) and returns the result of joining up those strings when it's called.
// `createGreeter` accepts a string and
// returns a new function that accepts a name
// and when that function is called ties both strings together
function createGreeter(greeting) {
return function (name) {
return `${greeting}, ${name}.`;
}
}
// Both of these return a function that accepts a name
const goodevening = createGreeter('Good evening');
const expectingyou = createGreeter('I\'ve been expecting you');
// And now we just need to call those functions with the name
console.log(goodevening('Blofeld'));
console.log(expectingyou('Mr. Bond'));
You are returning inside the function greet the function itself
If you want to store in a var the result of greet function then you must call it:
Instead of return greet you should return greet()
The code says return greet on line 5. The value of greet is the function greet itself. You may want to change line 5 to return greet(), which would execute the greet() function and then return the return value of greet(), which itself is undefined.
While solving a programming challenge, I wrote a function which was intended to take a function as an argument and return a function as well. The returned function was meant to execute the argument function (which was passed to first function). The function's code :-
function func1(f){
let func2 = function(){
if(/*a condition based on a global variable*/){
f();
}
}
return func2;
}
This is currently not working and it raises an Illegal Invocation Type Error. I saw this question but I don't know how to relate it's answers to my code. So, my questions are :-
Why isn't my code working?
What can I do to make it work?
EDIT
I'm invoking the function like this :-
var someFunc = func1(alert);
someFunc("foo");
someFunc("bar");
You need to handle
the context of the function call
the arguments
the returned value
Here's an implementation:
function func1(f, context){
let func2 = function(){
if( some condition ){
return f.apply(context, arguments);
} // there probably should be some "else" behavior...
}
return func2;
}
With some example uses:
var fun = func1(console.log, console);
fun("A", 25); // logs "A", 25
fun = func1(alert);
fun("foo"); // alerts "foo"
Why don't you use var instead of let
function func1(f){
var func2 = function(){
if(/*a condition based on a global variable*/){
f();
}
}
return func2;
}
I've been learning JavaScript and AngularJS and have been seeing functions with an extra set of parentheses. What is this? How does it work?
e.g.: myFunc(args)(moreArgs).
The extra set is for running and returning another function. So, using your example: myFunc will take one argument and return a second function (can be anonymously named):
function myFunc(args) {
return function (moreArgs) {
return args + ' ' + moreArgs;
};
}
var myMsg = myFunc("This")("works!");
alert(myMsg);
In javascript a function can return a function and that returned function can be called immediately. For example:
function a () {
return function () {
console.log('hello');
}
}
One way of calling the returned function is:
var b = a(); // b is now a function returned by a
b(); // logs "hello"
But in javascript you can also do:
a()(); // calls the returned function immediately, logs "hello"
I'm stuck with this concept of 'Functions that return functions'. I'm referring the book 'Object Oriented Javascript' by Stoyan Stefanov.
Snippet One:
function a() {
alert("A!");
function b() {
alert("B!");
}
return b();
}
var s = a();
alert("break");
s();
Output:
A!
B!
break
Snippet Two
function a() {
alert('A!');
function b(){
alert('B!');
}
return b;
}
var s = a();
alert('break');
s();
Output:
A!
break
B!
Can someone please tell me the difference between returning b and b() in the above snippets?
Assigning a variable to a function (without the parenthesis) copies the reference to the function. Putting the parenthesis at the end of a function name, calls the function, returning the functions return value.
Demo
function a() {
alert('A');
}
//alerts 'A', returns undefined
function b() {
alert('B');
return a;
}
//alerts 'B', returns function a
function c() {
alert('C');
return a();
}
//alerts 'C', alerts 'A', returns undefined
alert("Function 'a' returns " + a());
alert("Function 'b' returns " + b());
alert("Function 'c' returns " + c());
In your example, you are also defining functions within a function. Such as:
function d() {
function e() {
alert('E');
}
return e;
}
d()();
//alerts 'E'
The function is still callable. It still exists. This is used in JavaScript all the time. Functions can be passed around just like other values. Consider the following:
function counter() {
var count = 0;
return function() {
alert(count++);
}
}
var count = counter();
count();
count();
count();
The function count can keep the variables that were defined outside of it. This is called a closure. It's also used a lot in JavaScript.
Returning the function name without () returns a reference to the function, which can be assigned as you've done with var s = a(). s now contains a reference to the function b(), and calling s() is functionally equivalent to calling b().
// Return a reference to the function b().
// In your example, the reference is assigned to var s
return b;
Calling the function with () in a return statement executes the function, and returns whatever value was returned by the function. It is similar to calling var x = b();, but instead of assigning the return value of b() you are returning it from the calling function a(). If the function b() itself does not return a value, the call returns undefined after whatever other work is done by b().
// Execute function b() and return its value
return b();
// If b() has no return value, this is equivalent to calling b(), followed by
// return undefined;
return b(); calls the function b(), and returns its result.
return b; returns a reference to the function b, which you can store in a variable to call later.
Returning b is returning a function object. In Javascript, functions are just objects, like any other object. If you find that not helpful, just replace the word "object" with "thing". You can return any object from a function. You can return a true/false value. An integer (1,2,3,4...). You can return a string. You can return a complex object with multiple properties. And you can return a function. a function is just a thing.
In your case, returning b returns the thing, the thing is a callable function. Returning b() returns the value returned by the callable function.
Consider this code:
function b() {
return 42;
}
Using the above definition, return b(); returns the value 42. On the other hand return b; returns a function, that itself returns the value of 42. They are two different things.
When you return b, it is just a reference to function b, but not being executed at this time.
When you return b(), you're executing the function and returning its result.
Try alerting typeof(s) in your examples. Snippet b will give you 'function'. What will snippet a give you?
Imagine the function as a type, like an int. You can return ints in a function.
You can return functions too, they are object of type "function".
Now the syntax problem: because functions returns values, how can you return a function and not it's returning value?
by omitting brackets! Because without brackets, the function won't be executed! So:
return b;
Will return the "function" (imagine it like if you are returning a number), while:
return b();
First executes the function then return the value obtained by executing it, it's a big difference!
Snippet one:
function a() {
alert('A!');
function b(){
alert('B!');
}
return b(); //return nothing here as b not defined a return value
}
var s = a(); //s got nothing assigned as b() and thus a() return nothing.
alert('break');
s(); // s equals nothing so nothing will be executed, JavaScript interpreter will complain
the statement 'b()' means to execute the function named 'b' which shows a dialog box with text 'B!'
the statement 'return b();' means to execute a function named 'b' and then return what function 'b' return. but 'b' returns nothing, then this statement 'return b()' returns nothing either.
If b() return a number, then ‘return b()’ is a number too.
Now ‘s’ is assigned the value of what 'a()' return, which returns 'b()', which is nothing, so 's' is nothing (in JavaScript it’s a thing actually, it's an 'undefined'. So when you ask JavaScript to interpret what data type the 's' is, JavaScript interpreter will tell you 's' is an undefined.) As 's' is an undefined, when you ask JavaScript to execute this statement 's()', you're asking JavaScript to execute a function named as 's', but 's' here is an 'undefined', not a function, so JavaScript will complain, "hey, s is not a function, I don't know how to do with this s", then a "Uncaught TypeError: s is not a function" error message will be shown by JavaScript (tested in Firefox and Chrome)
Snippet Two
function a() {
alert('A!');
function b(){
alert('B!');
}
return b; //return pointer to function b here
}
var s = a(); //s get the value of pointer to b
alert('break');
s(); // b() function is executed
now, function 'a' returning a pointer/alias to a function named 'b'. so when execute 's=a()', 's' will get a value pointing to b, i.e. 's' is an alias of 'b' now, calling 's' equals calling 'b'. i.e. 's' is a function now. Execute 's()' means to run function 'b' (same as executing 'b()'), a dialog box showing 'B!' will appeared (i.e. running the 'alert('B!'); statement in the function 'b')
Create a variable:
var thing1 = undefined;
Declare a Function:
function something1 () {
return "Hi there, I'm number 1!";
}
Alert the value of thing1 (our first variable):
alert(thing1); // Outputs: "undefined".
Now, if we wanted thing1 to be a reference to the function something1, meaning it would be the same thing as our created function, we would do:
thing1 = something1;
However, if we wanted the return value of the function then we must assign it the return value of the executed function. You execute the function by using parenthesis:
thing1 = something1(); // Value of thing1: "Hi there, I'm number 1!"
Here is a nice example to show how its work in practice:
when you call in with two parameter and returns a result
function sum(x, y) {
if (y !== undefined) {
return x + y;
} else {
return function(y) { return x + y; };
}
}
console.log(sum(3)(8))
there is also another way using the accessing to the arguments in js:
function sum(x) {
if (arguments.length == 2) {
return arguments[0] + arguments[1];
} else {
return function(y) { return x + y; };
}
}
Let's try to understand the "return" concept with two examples with the same output, one without using the "return" concept and the other with the "return" concept, both giving the same outcome.
let myLuckyNumber = 22
function addsToMyLuckyNumber(incrementBy, multiplyBy) {
myLuckyNumber = (myLuckyNumber + incrementBy) * multiplyBy
}
addsToMyLuckyNumber(5, 2)
console.log(myLuckyNumber)
const myLuckyNumber = 22
function addsToMyLuckyNumber(incrementBy, multiplyBy) {
return (myLuckyNumber + incrementBy) * multiplyBy
}
myNewLuckyNumber = addsToMyLuckyNumber(5,2)
console.log(myLuckyNumber, myNewLuckyNumber)
In the first snippet, you can see the code
myLuckyNumber = (myLuckyNumber + incrementBy) * multiplyBy
you cannot assign a similar code to the second snippet, since it will not work, so we use "return" concept and assign a new variable.
function addsToMyLuckyNumber(incrementBy, multiplyBy) {
return (myLuckyNumber + incrementBy) * multiplyBy
}
myNewLuckyNumber = addsToMyLuckyNumber(5,2)
I understand calling function(1) but not function(1)(2), how does it work?
also possible for function(1)(2)(3)(4) too?
In this case you are supposing that function(1) returns a function, than you are calling this new, anonymous function with an argument of 2.
See this example:
function sum(a) {
return function(b) {
return a+b;
}
}
// Usage:
window.alert(sum(5)(3)); // shows 8
var add2 = sum(2);
window.alert(add2(5)); // shows 7
window.alert(typeof(add2)); // shows 'function'
Here we create a function sum that takes one argument. Inside the function sum, we create an anonymous function that takes another argument. This anonymous function is returned as the result of executing sum.
Note that this anonymous function is a great example of what we call closure. A closure is a function that keeps the context in which it was created. In this case, it will keep the value of the variable a inside it, as did the example function add2. If we create many closures, they are independent as you can see:
var add3 = sum(3);
var add4 = sum(4);
window.alert(add3(3)); // shows 6
window.alert(add4(3)); // shows 7
Furthermore, they won't get "confused" if you have similarly named local variables:
var a = "Hello, world";
function multiply(a) {
return function(b) {
return a * b;
}
}
window.alert(multiply(6)(7)); // shows 42
var twoTimes = multiply(2);
window.alert(typeof(twoTimes));
window.alert(twoTimes(5));
So, after a call to sum(2) or multiply(2) the result is not a number, nor a string, but is a function. This is a characteristic of functional languages -- languages in which functions can be passed as parameters and returned as results of other functions.
You have a function that returns a function:
function f(n) {
return function(x) {
return n + x;
};
}
When you call f(1) you get a reference to a function back. You can either store the reference in a variable and call it:
var fx = f(1);
var result = fx(2);
Or you can call it directly:
var result = f(1)(2);
To get a function that returns a function that returns a function that returns a function, you just have to repeat the process:
function f(n) {
return function(x) {
return function(y) {
return function(z) {
return n + x + y + z;
}
}
};
}
If your function returns a function, you can call that too.
x = f(1)(2)
is equivalent to:
f2 = f(1)
x = f2(2)
The parenthesis indicate invocation of a function (you "call" it). If you have
<anything>()
It means that the value of anything is a callable value. Imagine the following function:
function add(n1) {
return function add_second(n2) {
return n1+n2
}
}
You can then invoke it as add(1)(2) which would equal 3. You can naturally extend this as much as you want.