Concept about anonymous function and invoke in javascript [duplicate] - javascript

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 4 years ago.
Now I have to solve a exercise in the exercise from freecodecamp.
The outcome are expected as follows:
addTogether(2, 3) should return 5.
addTogether(2)(3) should return 5.
addTogether("This is sth") should return undefined.
addTogether(2, "3") should return undefined.
addTogether(2)([3]) should return undefined.
And by referring to some suggested solutions, one of the solutions is like:
function add(){
var args= [].slice.call(arguments);
if (!args.every(function(argument){return typeof argument === 'number';})){
return undefined;
}
if(args.length === 2){
return args[0] + args[1];
} else {
var a = args[0];
var addOne = function(b){
return add(a,b);
};
return addOne;
}
return false
}
add(2)(3)
In here, I am not really sure, why in the variable addOne, the anonymous function will successfully capture the the value in the second brackets, after calling the first value before?
I seek for the information about JavaScript function invocation, but still do not 100% sure why...
Edited:
With the features of closure, because I have already extracted the first parentheses, the next closure i.e the function, will automatically take the second input? And in this case, if I want to do addTogether(2)(3)(4)(5) , then I can do that by creating closures within different parentheses e.g
var a = args[0];
var addOne = function(b){
var addTwo = function(c){
var addThree = function(d){
return a+b+c+d;
}
}
};
Do I understand in the correct sense?

In here, I am not really sure, why in the variable addOne, the
anonymous function will successfully capture the the value in the
second brackets, after calling the first value before?
Because, when you say, addTogether(2), it means you're calling a function and passing it an integer 2, and when you say addTogether(2)(3), it means, you're calling a function and passing it an integer 2, which is then returning a function, to which you're passing the integer 3.
So, when the code says return addOne, it is returning the function which is called with the second parentheses, (3), so addTogether gets the value 2 and the return of addTogether, which is addOne gets the value 3.

Related

Higher order function Javascript

I am new to Javascript, and sturdying about the concept of higher order function, and using function as parameters.
I got two examples of code from online, and I do not understand what is going to happen.
First one, output will be 0, and I could not print the time of t1 and t2 ( I tried console.log(t1), but it became reference error). I wonder why it became 0.
Also, I don't get how funcParameter() that is inside of functionbody is working for the function, though I know funcparameter() is callback function, and which is addOneToOne().
Second one, output will be 3. but how can it be 3 even though, I haven't put parameter into addTwo()? If I have not put anything in parameter, num will be automatically 0 or undefined?
I am sorry for many questions, but I really appreciate if you could help me out.
//1st code
const timeFuncRuntime = funcParameter => {
let t1 = Date.now();//
funcParameter();
let t2 = Date.now();//
return t2 - t1;
}
const addOneToOne = () => 1 + 1;
timeFuncRuntime(addOneToOne);
console.log(timeFuncRuntime(addOneToOne))//0
//2nd code
const addTwo = num => num + 2;
const checkConsistentOutput = (func, val) => {
let firsttry = func(val);
let secondtry = func(val);
if(firsttry === secondtry){
return firsttry;
} else {
return 'This function returned inconsistent results';
}
};
checkConsistentOutput(addTwo,1)
console.log(checkConsistentOutput(addTwo,1))//3
1: The scope of the t1 variable is limited to the function block. You can read more about variables scope here
2: You are using val as function parameter, and the value of val is 1.
1 + 2 = 3
The 1 is in this line:
checkConsistentOutput(addTwo,1)
First one, output will be 0, and I could not print the time of t1 and t2 ( I tried console.log(t1), but it became reference error). I wonder why it became 0.
Because zero milliseconds passed between the first call to the callback and the second. Date.now() works in milliseconds. The call probably took microseconds at most.
You couldn't access t1 or t2 because they're local variables in the timeFuncRuntime function, so you can't access those variables outside the timeFuncRuntime function, only inside it.
Also, I don't get how funcParameter() that is inside of functionbody is working for the function, though I know funcparameter() is callback function, and which is addOneToOne().
Functions are objects in JavaScript. When you do timeFuncRuntime(addOneToOne), you're passing a reference to the function into timeFuncRuntime which it receives as the value of the funcParameter parameter. So when that code does funcParameter(), it's calling addOneToOne.
Second one, output will be 3. but how can it be 3 even though, I haven't put parameter into addTwo()?
Because checkConsistentOutput did it. When you do console.log(checkConsistentOutput(addTwo,1)), you're passing a reference to addTwo and the number 1 into checkConsistentOutput. It receives them as its func and val parameters. So when it does func(val), it's calling addTwo with the value 1. It gets the result in the firsttry variable, then does the call again and gets the result in secondtry, and since they match, it returns the value of firsttry, which is 3.
Second one, output will be 3. but how can it be 3 even though, I haven't put parameter into addTwo()?
You copy the function stored in addTwo as the first argument to checkConsistentOutput where it gets assigned to func. Then you call the function here — let firsttry = func(val); — and here — let secondtry = func(val);

ES6 functions help - functions returning functions [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
i am very new to ES6.
Trying to go through some tests to learn.
Please help me on this on what should be the implementation to pass the tests.
// dependencies:
const expect = require('chai').expect;
// implement this:
function b(x){
// return "b"+ x;
// return (x) => "bo" + x;
}
// unit tests:
describe("implement function b", function() {
it("SHOULD work for the following cases", function() {
console.log(b()("m"));
expect(b("m")).to.equal("bm");
expect(b()("m")).to.equal("bom");
expect(b()()("m")).to.equal("boom");
expect(b()()()("m")).to.equal("booom");
expect(b()()()()("t")).to.equal("boooot");
});
});
This is possible but a bit weird and I would never do something like this in real life.
In general, a function that returns a function is called a "second-order" function. A function that returns a function that returns a function is a "third-order" function. What you're trying to do is write a function that is has a different order depending on the arguments, which is really confusing to read and maintain.
Having said that, javascript isn't fussy about return types, so you can do it. Here's the code I'd use (uses ES6 default variables and recursion)
function b(lastLetter, prefix = "b") {
if (lastLetter) {
//if we're ending the chain, return everything so far with the last letter on the end
return prefix + lastLetter;
}
//if not, then return version of this function with a slightly longer prefix
return lastLetter => b(lastLetter, prefix + "o");
}
console.log( b("m") );
console.log( b()("m") );
console.log( b()()("m") );
console.log( b()()()()()()()("t") );
You can use a closure and named function expression, see comments. I don't like the repeated line but can't avoid it with this pattern.
function b(x) {
// On the first call, setup prefix
var prefix = 'b';
// End early if x provided on first call
if (x) return prefix + x;
// Otherwise, return a function that can be chained
return function foo(x){
prefix += 'o';
if (x) return prefix + x;
return foo;
}
}
console.log(b('m'));
console.log(b()('m'));
console.log(b()()('m'));
console.log(b()()()('m'));
console.log(b()()()()('t'));
The problems with this pattern are:
If no letter is provided in the last call, it returns a function. There's no way for a particular call to know it's the last.
If a call is made after a letter is provided, it will attempt to call a string, which will throw an error. Again, there's no way to stop the call once a letter is provided if the user attempts it.
Obviously, b has to return a function if no argument is passed to it. This function acts the same way: if no argument is passed to it, it returns itself. Moreover, we have to keep track of how many times our function was called.
The following solution creates an inner function which increments the count if its argument is falsy, otherwise it creates a string that consists of "b", "o" repeated as many times as the count specifies and the value of the argument:
const b = v => {
let n = 0; // this is our counter
const f = e => {
if (e !== undefined) {
// an argument was passed, return the correct value
return 'b' + 'o'.repeat(n) + e;
}
// no argument was passed, increment the counter and return the function
n += 1;
return f;
};
// call the function the first time with the initial value
return f(v);
};
console.log(b('m'));
console.log(b()('m'));
console.log(b()()('m'));
console.log(b()()()('m'));
console.log(b()()()('t'));

Nested functions, non defined variable-Javascript

I'm learning javascript and I found this exercise:
function abc(a){
return(function(y){
return y--**--y+1;
})(++a)+a;
}
document.write(abc(2));
The output of that is 7 and I dont understand why, I searched information about nested functions and I didnt found anything....
How is "y" defined?
this function translates to:
//I've replaced the arguments and the vars with the actual values
function abc(){
function innerFunction(){
return (3 ** 1) + 1
}
return innerFunction(3) + 3
}
//or written differently
function abc(a){
function innerFunction(v){
//v--
var tmp1 = v;
v = v-1;
//--v
v = v-1;
var tmp2 = v;
return Math.pow(tmp1, tmp2) + 1;
}
a = a+1; //++a
return innerFunction(a) + a;
}
That is easy.
Function abc return (function(y){ return y--**--y+1; })(++a)+a
this means if a is 2 (function(3){ return y--**--y+1; }) + 2
This contains an immediately invoked function expression (IIFE).
Here's an example that might clarify how they work:
(function(x) { return x; })(10); // Returns 10
The value inside the parenthesis is used as the function's argument as soon as the function is defined. So, in this case, the function is set to return the argument, and immediately afterwards, it is given the value 10.
On your example, with some added whitespace:
return (function(y) {
return y-- ** --y + 1;
})(++a)
+ a
What's happening is the same. A function is being defined then, immediately afterwards, it receives the argument ++a. It will replace all instances of y by the value contained in ++a. Then, as that is returned, it goes through + a, so it adds a to the result.

Is it possible to add a value when returning a function from a recursive function being chained? [duplicate]

I'm trying to solve a puzzle, and am at my wit's end trying to figure it out.
I'm supposed to make a function that works like this:
add(1); //returns 1
add(1)(1); //returns 2
add(1)(1)(1); //returns 3
I know it can be done because other people have successfully completed the puzzle. I have tried several different ways to do it. This is my most recent attempt:
function add(n) {
//Return new add(n) on first call
if (!(this instanceof add)) {
return new add(n);
}
//Define calc function
var obj = this;
obj.calc = function(n) {
if (typeof n != "undefined") {
obj.sum += n;
return obj.calc;
}
return obj.sum;
}
//Constructor initializes sum and returns calc(n)
obj.sum = 0;
return obj.calc(n);
}
The idea is that on the first call, a new add(n) is initialized and calc(n) is run. If calc receives a parameter, it adds n to sum and returns itself. When it eventually doesn't receive a parameter, it returns the value of sum.
It makes sense in theory, but I can't get it to work. Any ideas?
--edit--
My code is just the route I chose to go. I'm not opposed to a different approach if anyone can think of one.
To answer "how dow this work". Given:
function add(n) {
function calc(x) {
return add(n + x);
}
calc.valueOf = function() {
return n;
}
return calc;
}
var sum = add(1)(2)(3); // 6
When add is called the first time, it stores the value passed in in a variable called n. It then returns the function calc, which has a closure to n and a special valueOf method (explained later).
This function is then called with a value of 2, so it calls add with the sum of n + x, wich is 1 + 2 which 3.
So a new version of calc is returned, this time with a closure to n with a value of 3.
This new calc is called with a value of 3, so it calls add with n + x, which this time is 3 + 3 which is 6
Again add returns a new calc with n set to 6. This last time, calc isn't called again. The returned value is assigned to the variable sum. All of the calc functions have a special valueOf method that replaces the standard one provided by Object.prototype. Normally valueOf would just return the function object, but in this case it will return the value of n.
Now sum can be used in expressions, and if its valueOf method is called it will return 6 (i.e. the value of n held in a closure).
This seems pretty cool, and sum will act a lot like a primitve number, but it's actually a function:
typeof sum == 'function';
So be careful with being strict about testing the type of things:
sum * 2 // 12
sum == 6 // true
sum === 6 // false -- oops!!
Here's a somewhat streamlined version of #RobG's great answer:
function add(n) {
function calc(x) { return n+=x, calc; }
calc.valueOf = function() { return n; };
return calc;
}
The minor difference is that here calc just updates n and then returns itself, rather than returning itself via another call to add, which puts another frame on the stack.
Making self-replication explicit
calc is thus a pure self-replicating function, returning itself. We can encapsulate the notion of "self replication" with the function
function self_replicate(fn) {
return function x() {
fn.apply(this, arguments);
return x;
};
}
Then add could be written in a possibly more self-documenting way as
function add(n) {
function update(x) { n += x; }
var calc = self_replicate(update);
calc.valueOf = function() { return n; };
return calc;
}
Parallel to Array#reduce
Note that there is a certain parallelity between this approach to repeatedly calling a function and Array#reduce. Both are reducing a list of things to a single value. In the case of Array#reduce the list is an array; in our case the list is parameters on repeated calls. Array#reduce defines a standard signature for reducer functions, namely
function(prev, cur)
where prev is the "accumulator" (value so far), cur is the new value being fed in, and the return value becomes the new value the accumulator. It seems useful to rewrite our implementation to make use of a function with that kind of signature:
function add(n) {
function reducer(prev, cur) { return prev + cur; }
function update(x) { n = reducer(n, x); }
var calc = self_replicate(update);
calc.valueOf = function() { return n; };
return calc;
}
Now we can create a more general way to create self-replication-based reducers based on a reducer function:
function make_repeatedly_callable_function(reducer) {
return function(n) {
function update(x) { n = reducer(n, x); }
var calc = self_replicate(update);
calc.valueOf = function() { return n; };
return calc;
};
}
Now we can create add as
var add = make_repeatedly_callable_function(function(prev, cur) { return prev + cur; });
add(1)(2);
Actually, Array#reduce calls the reducer function with third and fourth arguments, namely the index into the array and the array itself. The latter has no meaning here, but it's conceivable we might want something like the third argument to know what "iteration" we're on, which is easy enough to do by just keeping track using a variable i:
function reduce_by_calling_repeatedly(reducer) {
var i = 0;
return function(n) {
function update(x) { n = reducer( n, x, i++); }
var calc = self_replicate(update);
calc.valueOf = function() { return n; };
return calc;
};
}
Alternative approach: keeping track of values
There are certain advantages to keeping track of the intermediate parameters the function is being called with (using an array), and then doing the reduce at the end instead of as we go along. For instance, then we could do Array#reduceRight type things:
function reduce_right_by_calling_repeatedly(reducer, initialValue) {
var array_proto = Array.prototype,
push = array_proto.push,
reduceRight = array_proto.reduceRight;
return function(n) {
var stack=[],
calc = self_replicate(push.bind(stack));
calc.valueOf = reduceRight.bind(stack, reducer, initialValue);
return calc(n);
};
}
Non-primitive objects
Let's try using this approach to build ("extend") objects:
function extend_reducer(prev, cur) {
for (i in cur) {
prev[i] = cur[i];
}
return prev;
}
var extend = reduce_by_calling_repeatedly(extend_reducer);
extend({a: 1})({b: 2})
Unfortunately, this won't work because Object#toValue is invoked only when JS needs a primitive object. So in this case we need to call toValue explicitly:
extend({a: 1})({b: 2}).toValue()
Thanks for the tip on valueOf(). This is what works:
function add(n) {
var calc = function(x) {
return add(n + x);
}
calc.valueOf = function() {
return n;
}
return calc;
}
--edit--
Could you please explain how this works? Thanks!
I don't know if I know the correct vocabulary to describe exactly how it works, but I'll attempt to:
Example statement: add(1)(1)
When add(1) is called, a reference to calc is returned.
calc understands what n is because, in the "mind" of the interpreter, calc is a function child of add. When calc looks for n and doesn't find it locally, it searches up the scope chain and finds n.
So when calc(1) is called, it returns add(n + x). Remember, calc knows what n is, and x is simply the current argument (1). The addition is actually done inside of calc, so it returns add(2) at this point, which in turn returns another reference to calc.
Step 2 can repeats every time we have another argument (i.e. (x)).
When there aren't any arguments left, we are left with just a definition of calc. The last calc is never actually called, because you need a () to call a function. At this point, normally the interpreter would return a the function object of calc. But since I overrode calc.valueOf it runs that function instead.
When calc.valueOf runs, it finds the most recent instance of n in the scope chain, which is the cumulative value of all previous n's.
I hope that made some sense. I just saw #RobG 's explanation, which is admittedly much better than mine. Read that one if you're confused.
Here's a variation using bind:
var add = function _add(a, b) {
var boundAdd = _add.bind(null, a + b);
boundAdd.valueOf = function() {
return a + b;
}
return boundAdd;
}.bind(null, 0);
We're taking advantage of a feature of bind that lets us set default arguments on the function we're binding to. From the docs:
bind() also accepts leading default arguments to provide to the target
function when the bound function is called.
So, _add acts as a sort of master function which takes two parameters a and b. It returns a new function boundAdd which is created by binding the original _add function's a parameter to a + b; it also has an overridden valueOf function which returns a + b (the valueOf function was explained quite well in #RobG's answer).
To get the initial add function, we bind _add's a parameter to 0.
Then, when add(1) is called, a = 0 (from our initial bind call) and b = 1 (passed argument). It returns a new function where a = 1 (bound to a + b).
If we then call that function with (2), that will set b = 2 and it'll return a new function where a = 3.
If we then call that function with (3), that will set b = 3 and it'll return a new function where a = 6.
And so on until valueOf is called, at which point it'll return a + b. Which, after add(1)(2)(3), would be 3 + 3.
This is a very simple approach and it meets the criteria the OP was looking for. Namely, the function is passed an integer, keeps track of that integer, and returns itself as a function. If a parameter is not passed - the function returns the sum of the integers passed to it.
let intArray = [];
function add(int){
if(!int){
return intArray.reduce((prev, curr) => prev + curr)
}
intArray.push(int)
return add
}
If you call this like so:
console.log(add(1)(1)());
it outputs 2.

javascript mystery - how functions get access to outside variables [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 7 years ago.
I am kind of new to javascript and trying to understand some non trivial - at least so i hope :) things.
my question is general, but i have a specific example which can help me ask my question and help you understand what i mean.
the example:
function updateBookmark(bookmark){
var index = _.findIndex($scope.bookmarks, function(b){
return b.id == bookmark.id;
});
return index;
}
obviously the findIndex function is declared somewhere (in our case - lodash.js)
and it gets two parameters (at least two visible parameters: a data set, and a function)
first question:
in this example, what is b? how does b gets its value? i understand b is each of the data set's objects, but i mean - what is going behind the scenes here so b will be what it is??
second question:
the author chose to pass an anonymous function which equals b.id with bookmark.id,
i understand that he can use bookmark.id where he is using it, but how does findIndex has access to this bookmark?!
this function as i concluded earlier is declared somewhere else, does it get all the variables in the scope some how?
what is going on here?
Thanks in advance to responders and sorry for the messy question...
Jim.
If you rewrite some things, it becomes easier to understand.
Starting with the last portion:
// Q: "How does `findIndex`have access to `bookmark`"
_.findIndex(bookmarks, function (b) { });
// A: "It doesn't."
var bookmark = { id: 1 };
var bookmarks = [ /* ... */ ];
function compareWithBookmark( test ) {
return test.id === bookmark.id;
}
_.findIndex(bookmarks, compareWithBookmark);
As you can see, findIndex doesn't actually have any access to bookmark.
Rather, it has access to a function which it can pass a value to test, and that function will return whether that test passed or failed.
Under the covers of .findIndex or [].map or [].filter, they're all just taking a function, making a loop, passing each element into the function one at a time, and doing something with the return value.
function findIndex (array, test) {
var index = -1;
var i = 0;
var l = array.length;
var el;
var result;
for (; i < l; i += 1) {
el = array[i]; // <-- how `b` got its value
result = test(el, i, array); // <-- test(b)
if (!!result) {
index = i;
break;
}
}
return index;
}
The different functions would do different things with the results (map returns a new array which contains each result, filter returns an array where only !!result tests passed, et cetera), but all of them do this inner-looping.
This is also a pretty gross simplification of the looping structure and considerations, but it's exactly what's driving your expected behaviour.
Edit
Here is a full usage of the function I just defined, plus the array, plus the object I'm checking.
var bookmarks = [
{ id: 2 },
{ id: 3 },
{ id: 6 },
{ id: 14 }
];
var bookmark = { id: 3 };
function compareBookmarkIdTest (el) {
return el.id === bookmark.id;
}
var index = findIndex(bookmarks, compareBookmarkIdTest);
index; // 1
Hope that helps.

Categories