I am new to programming and trying to understand callback functions and functions in general. This program compares 2 values passed in the functions(using callback) and return true/false to us.
function func1(param1, callback) {
return callback(param1);
}
function func2(param2) {
return function(param3) {
return param3 > param2;
}
}
var functionResult = func1(10, func2(9));
console.log(functionResult); // prints - true
Question - In this program above, how does the return function inside the func2 function, return the value directly to us, without being invoked? I thought in this line var functionResult = func1(10, func2(9)); func2(9) will return only the text
function(param3) {
return param3 > param2;
}
and then I would have to invoke it again with ().
how does the return function inside the func2 function, return the value directly to us, without being invoked?
It is invoked. func1 invokes it here:
callback(param1)
func2(9) will return only the text ...
That's not text, that's actually a function (object). It is passed to func1 which in turn calls it and returns its return value.
and then I would have to invoke it again with ().
Yes, which, again, is what func1 does:
callback(param1)
Lets take things apart:
var functionResult = func1(10, func2(9));
is the same as
var func2Result = func2(9);
var functionResult = func1(10, func2Result);
Since we know what func1 does, we can replace the call to it with it's implementation. 10 is passed as param1 and func2Result is passed as callback, so the code becomes:
var func2Result = func2(9);
var functionResult = func2Result(10); // callback(param1);
Now you should be able to see that the return value of func2 is actually called.
Related
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.
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 am currently reading Eloquent Javascript Chapter 5. They give the following example which is confusing the hell out of me.
function greaterThan(n) {
return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
// → true
Can anyone break this down to me as simply as possible. I have huge trouble with callbacks. Especially when it comes to situations like these.
Higher-Order functions basically mean two things:
Functions can take other functions as an argument/input
Functions can return functions
This is what is meant by higher-order functions.
// this function takes a function as an argument
function myFunc(anotherFunc) {
// executes and returns its result as the output which happens to be a function (myFunc)
return anotherFunc();
}
// let's call myFunc with an anonymous function
myFunc(function() {
// this returns a function as you see
return myFunc;
});
As for your example, it demonstrates higher-order functions by returning a function. It also demonstrates the notion of closure.
Closure is closing over a scoped variable, in this case the input argument n.
function greaterThan(n) {
// n is closed over (embedded into and accessible within) the function returned below
return function(m) { return m > n; };
}
// greatherThan10 reference points to the function returned by the greaterThan function
// with n set to 10
// Notice how greaterThan10 can reference the n variable and no-one else can
// this is a closure
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
// → true
There's no "callback" involved here. What you've got with the "greaterThan" function is a function that returns another function.
So, you call the function:
var greaterThan10 = greaterThan(10);
Now the variable "greaterThan10" references the function returned by the "greaterThan" function invoked with 10 as the argument.
Then, you log the result of calling that function:
console.log(greaterThan10(11));
The function returned from "greaterThan" is invoked. It compares its parameter to the value of the parameter "n" passed when it was created. Because 11 is in fact greater than 10, the function will return true and that's what'll be logged.
Taken from Secrets of the JavaScript Ninja, Listing 5.14 passes the num argument of isPrime to a memoized function, I assumed the num argument would be visible in #1, and not in #2, But it's actually The other way around!
Function.prototype.memoized = function(key){
this._values = this._values || {};
return this._values[key] !== undefined ?
this._values[key] :
this._values[key] = this.apply(this, arguments);
};
Function.prototype.memoize = function() {
var fn = this; //#1
console.log(Array.prototype.slice.call(arguments)); // Prints []
return function(){ //#2
console.log(Array.prototype.slice.call(arguments)); //Prints [17]
return fn.memoized.apply(fn, arguments);
};
};
var isPrime = (function(num) {
var prime = num != 1;
for (var i = 2; i < num; i++) {
if (num % i == 0) {
prime = false;
break;
}
}
return prime;
}).memoize();
assert(isPrime(17), "17 is prime"); //#3
How is it possible that the num argument (17 in this case) is visible only in the inner closure (#2) and not in the wrapping memoize function? I don't understand at which point the memoize() call passes the num argument to the closure in #2.
PS. To reiterate, and complement the Question above: Why can't I see the num argument in #1?
Thank you.
Because #2 is the function that is assigned to isPrime. And you pass 17 to isPrime. On the other hand, you call .memoize (#1) without passing any arguments to it:
(function() { ... }).memoize()
// ^^ no arguments
I don't understand at which point the memoize() call passes the num argument to the closure in #2.
It doesn't. memoize returns a new function and it's that function to which the argument is passed.
Because at that point, the anonymous function has't been called.
What you are doing is calling memoize, with your anonymous function as the this value and no arguments (hence the empty arguments array)
memoize then returns a function, which basically checks "has this function already been called with this argument", and either return the previous value if so, or calls the function and stores its return value if not.
What this means is that your function is only called when you actually do isPrime(17), and at that point your are inside the function where it says return function() {...} and that's where you can see your argument.
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.