Confusion about variables equaling functions JavaScript - javascript

I have these functions:
function change(num1, num2){
//return number
}
function getFunction(funct){
//return function
}
this declaration:
var funct = getFunction(change);
and this call
funct(array);
I am confused about what the call does. Where does it send array, what exactly is it doing? I just can't wrap my head around it. When sending the function change() into getFunction() what exactly does this do and again how does JS handle funct(array)? Let me know if I need more info.

getFunction returns a function.
var funct = getFunction(change);
funct is now assigned to the returned function reference
funct(array) is just calling the function returned from the previous assignment.

Related

Why function returns unexecuted

If I write this code:
var foo = function (){
var x = 5;
return (function (){ return x;})();
}
alert(foo());
it alerts 5, as intended. But, if I do not use IIFE:
var foo = function (){
var x = 5;
return function (){ return x;};
}
alert(foo());
it alerts
function(){return x;}
I understand that in the first example IIFE runs and whatever it computes gets returned.BUT, if not using IIFE function returns without being executed.
Why is function returned before it is executed?
Functions in JS are first class objects. You can treat them in the same way as you can treat any object, including pass them about between functions.
If you don't do something to call a function, then it doesn't get called.
So is function(){return x:} which gets alerted in the second option a string
It is a function.
Functions, like any object, have a toString method.
alert() expects to be passed a string. Since you pass it an object, it will get converted to a string, which is done by calling toString().
Basically you are not executing the function before returning anything in the second example. You are just returning a function definiton with this row: return function (){ return x;};. This is why the function returns just the function that you placed after the return.
Functions are never called automatically. They can be passed as arguments, returned as values, assigned to variables, etc. and this just moves around references to the function. In order to call a function, you have to use the () operator.
Your first example does this by calling the function in the IIFE. "II" stands for "Immediately Invoked", and refers to putting () right after the anonymous function expression, so that you define it and then immediately invoke it.
In your second example, you simply return the function, and then pass it as an argument to alert(). alert() has no reason to call the function (it's not like map() or forEach(), which take a callback argument and are specified to call the function). If you want to execute the function, you need to call it explicitly, e.g.
var foo = function() {
var x = 5;
return function() {
return x;
};
}
alert(foo()());
The double () means to first call foo, then call whatever it returns, and finally pass the result to alert.

Access a function which is being used as an argument to another function

I'm not sure how to explain this problem but I'll do my best.
Currently, I'm tackling the 'Default Arguments' kata on codewars. This involves creating a function 'defaultArguments', that can take another function as an argument, along with an object with the default values to be used. This function is then set to be equal to a variable which is then called with other arguments. Basically, the idea is to use the default arguments if no arguments are provided with the function call. But, the default arguments are not used when the argument is present. So, the tests provided on this kata are as follows:
function add(a,b) { return a+b; }
var add_ = defaultArguments(add,{b:9});
Test.assertEquals(add_(10), 19);
Test.assertEquals(add_(10,5), 15);
var add_ = defaultArguments(add_,{b:3});
Test.assertEquals(add_(10), 13);
I've managed to create a piece of code that will correctly function when the function is provided similar to the 'add' function. However, I'm now encountering the below function and my code is failing.
var closure_counter = (function accumulator() { var counter = 0; return function (x) { return counter += x; }; })();
I think this 'closure_counter' is then passed into the defaultArguments function as before.
However, to use the previous 'add' function as an example, the first stage in my program was to convert the function argument into a string:
function_string = func.toString();
And then use this string to basically isolate the code that needs to run. In the 'add' example, this would console.log the following:
FUNCTION STRING: function add(a,b) { return a+b; }
I would then return this along with other information using:
let new_function = new Function():
And the remainder of my programme would run. The problem seems to be when I encounter the above 'closure_counter' function. When I use the same func.toString() and console.log(), my output is this:
FUNCTION STRING: function (x) { return counter += x; }
So it basically misses the first part of the function which included the declaration of the variable counter. This is required for the execution of my code.
Basically, is there anyway to either access this variable later on in my code, or alternatively, to pass it into the func.toString() so I can isolate the variables I need?
Thanks and apologies if this is unclear!

closure in javascript working differently for me

Considering the following code snippet,
function outer(data1){
function inner(){
console.log(data1);
}
return inner;
}
in the following two function calls, first one works but not the second one.
var o = outer("sree");
o(); //works
outer("kumar"); //does not work
Please help me to understand better. Thanks.
Call like this:
outer("kumar")();
outer("kumar"); calling this will only get the reference of the inner function. By placing braces again it will call the inner function as well.
You're inner function has no parameters, you need to add one like this:
function outer(){
function inner(data1){
console.log(data1);
}
return inner;
}
You're code will always log in the console the parameter with which you created the object.
When you invoke the function outer("kumar") the function return a function, but that function is not invoked, that's the reason why this call do not log in console.
In the other hand, if you create a new variable invoking the function var o = outer("sree");, as I mentioned, the function outer return a function inner, then you invoke that function with the new variable created o();.
function outer(data1){
return (function inner(){
return data1;
});
}
The function outer returns another function 'inner', this is kind of a reference and to execute a function we need to call just like we called outer.
var o = outer("sree");
console.log(o());
The variable o contains ref to the function inner. to execute it we need to call (o()).
In your last action (console.log(outer("kumar"))), you have invoked first function and it resulted ref to 'inner' function, to get the output you have to invoke the second as well. The kumar will get printed as because the 'inner' method is with in the scope of the outer function.

why does a variable need to be created in this closure

Hi I have the following closure
function createCounter() {
var numberOfCalls = 0;
return function() {
return ++numberOfCalls;
}
}
var fn = createCounter();
fn()
fn()
And I believe I understand about scope and the fact that the inner function keep the outer function's values after the outer one has returned.
What I don't understand is why I need to create this variable
var fn = createCounter()
and then invoke the variable fn() instead of initially invoking createCounter()
I saw that createCounter() just returns 'function()' instead of what has to be '1' and I don't understand why.
Thanks for the help. Read many tutorials still having problems with understanding this.
Please note: the question's isn't about how to make the code more eloquent or better, it's about understanding of what's been done
When createCounter is called it returns another function and that returned function is not evaluated unless you do so. Remember, in JavaScript functions are objects too. They can be the return value of a function.
So when you do this:
var fn = createCounter();
fn references only the function returned by createCounterfunction and not its evaluated value.
If you need to evaluate the function returned by createCounter try something like:
createCounter()();
This evaluates the returned function.
If you call it like this it will always return the same value as it creates a new numberOfCalls variable every time you call createCounter.
In Javascript, functions are objects which can be passed to and returned by other functions, as any other objects (e.g. a string, a number...).
So doing:
function foo(arg) { /* ... */ }
var someObject = new String("Hello");
foo(someObject);
is similar as:
function foo(arg) { /* ... */ }
var someFunction = new Function("Hello", "...");
foo(someFunction);
A function may thus return another function, which can be invoked as needed.
function foo() {
return new Function(...);
}
var functionReturnedByCallingFoo = foo();
functionReturnedByCallingFoo(); // can be invoked
functionReturnedByCallingFoo(); // and again
functionReturnedByCallingFoo(); // and again
Now, functions are almost never declared using the Function constructor, but rather with constructs named "function declarations" or "function expressions" - basically, the way we have defined the function "foo" in the previous examples, with a function signature and a function body delimited by curly brackets.
In such cases, the statements inside of the function body can read and write variables declared outside of the function itself ("free variables"), and not only variables declared within the function, as per the rules of lexical scoping. This is what we call a closure.
So in your case, the createCounter() function, when invoked, defines a local variable named "numberOfCalls", then return a function - the body of which having access to that variable. Executing the returned function changes the value of the variable, at each invocation, as it would for any "global" variable (i.e. variables declared in outer scopes).
Executing the createCounter() function many times would simply, each time, recreate a new local variable "numberOfCalls", initialize it to zero, and return a new function object having access to that variable.

JS function returning another function

I want to understand about variables, that has been used in returning function.
This is example code
Prototype = {}
Prototype.F =
{
bind: function()
{
var args = arguments, __method = args.shift(), object = args.shift();
return function()
{
return __method.apply(object, args.concat(arguments));
}
}
}
function ObjectA()
{
...
this.addListener = Prototype.F.bind(this.eventSource.addListener,
this.eventSource);
...
}
var a = ObjectA();
a.addListener(this); // assuming 'this' here will point to some window object
As I understand the returning function in bind() is not evaluated until it's called in the last line. It's ok to accept. So addListener will hold a function body containing 'apply'.
But what I don't understand, when addListener is called, what kind of parameters it is going to have? particularly _method and args will always be uninitialized?
The function that bind returns is a closure over the arguments to the bind function, and so the __method argument will be the first argument to bind (in your example call, that will be the this.eventSource.addListener function).
Closures are basically functions that have data bound into them intrinsically. Here's a simpler example:
function makeAlert(msg) {
return function() {
alert(msg);
}
}
var myalert = makeAlert("Hi there!");
myalert(); // Alerts "Hi there!"
The function returned by makeAlert "closes over" (retains access to) the things in scope within the makeAlert function call that created it, including the msg argument. That's why when we call the function later, it still has msg even though the call to makeAlert has long since completed. More about closures here.
A key thing to remember about closures is that they retain access to everything that's in scope where they're defined, not just the things they they're obviously using. So for instance:
function init() {
var data;
data = /* ...build some really big array of data...*/;
document.getElementById('foo').onclick = function() {
this.style.display = "none";
};
}
Even though the event handler has nothing to do with the big data array, it keeps a reference to it, and so keeps that data in memory after the call to init has completed. This is because the link that it has is to a behind-the-scenes object (loosely called the "variable object") that is a container for all of the arguments and local variables in scope where it's defined. (In this particular case, if you don't need all that data, just set data to undefined at the end. The event handler will still have a reference to data, but that reference isn't holding the array anymore, so the array's memory can be reclaimed.)
_method and args will be always initialized, because you are defining them when you first call
this.addListener = Prototype.F.bind(this.eventSource.addListener, this.eventSource);
There, you'll get that _method will be that this.eventSource.addListener, and args will be those both arguments.
in the scope of a function, arguments is an array-like object which contains the values provided when the function is called, whether or not the function definition has parameters defined.
so for this call:
Prototype.F.bind(this.eventSource.addListener, this.eventSource);
which leads to this:
var args = arguments, __method = args.shift(), object = args.shift();
arguments contains 2 items: whatever this.eventSource.addListener and this.eventSource point to when the function is called. that collection of 2 items is copied to args, and then the items are moved from the colleciton to __method and object.
since the call bind actually generates another function, the arguments instance in the new function will be different- it'll have the parameters provided at the time of that call. the original arguments from the call to bind are saved in args and combined with arguments from the later function call.

Categories

Resources