Why function returns unexecuted - javascript

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.

Related

Attempting to pass a string to a constructed function

still floundering around in my attempts to understand functions. How would I go about constructing a function with values I want to pass to it?
var box = $('#box1');
function pushCard(arg1) {
if (this.style.opacity == 0.5) {
this.style.opacity = 1;
}
else {
this.style.opacity = 0.5;
window.alert(arg1);
}
}
box.click(pushCard('String'));
tl;dr: be aware of the difference between functions / function results and when functions are passed as values / when they're called (and their result is passed)
The culprit is with this line:
box.click(pushCard('String'));
You're calling box.click() with "something". JavaScript needs to evaluate expressions before passing them as function arguments.
In this case, you instruct JavaScrip to run box.click(pushCard('String')) = call box.click with value of pushCard('String') as first parameter.
In order to do this, JavaScript first needs to evaluate pushCard('String') by running pushCard with value 'String' as first parameter (this doesn't need more evaluation since it's already a value).
The result of pushCard('String') is undefined (you're returning nothing from that function). So in effect, it's the equivalent of box.click(undefined).
This is what you want:
box.click(function() {pushCard('String')});
(or with ES6 arrow functions: box.click(() => pushCard('String'));)
In this case, you're assigning box.click() a function. This is what jQuery .click()` expects, a click handler which will run (be evaluated) then the click happens, not when the click handler is assigned.
In JavaScript, you can pass functions as values, and they are evaluated when explicitly called:
function test() {
alert('I have been called');
}
function delay_it(handler) {
setTimeout(function() {
handler(); // ⇽ call given function
}, 1000);
// shorter: setTimeout(handler, 1000);
}
// Wrong (we're calling test() by ourselves and passing the result (undefined) to delay_it
delay_it(test());
// Correct (we're giving test as function to delay_it, delay_it will call the function)
delay_it(test);

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.

Confusion about variables equaling functions 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.

Why can we subsitute "foo" for "function (x) { return foo(x); }"

I was looking for lesser knows facts about JavaScript and I came across this piece, can anyone explain why the below code
function (x) { return foo(x); }
can be substituted with
foo
Tried to figure this out with the little knowledge of JavaScript which I had, but I didn't find the reason. Can anyone explain it?
Because
var bar1 = function (x) { return foo(x); };
var bar2 = foo;
And then
bar1(5);
bar2(5);
The first one will execute a function that will call foo(5), the second one will call foo(5) directly. Same end result.
The first is a function that takes one argument and returns whatever the result of foo with that argument is. The second is a function which takes one argument (presumably) and returns whatever the result of foo with that argument is (because it is the foo function).
The long version is just a wrapper around foo which doesn't add anything.
function(x){return foo(x);} actually is a nameless function which passes x to the function foo. The nameless function will return the result of foo(x) on the line return foo(x)
which is the same as calling foo(x) at the first place not form inside another function.
This code snippet assumes that foo is already a function in the current scope.
When you want to pass foo as a callback, you can do so directly:
function ITakeACallback(callback) {
callback(42); // and call it
}
ITakeACallback(foo);
So what you did here was pass to ITakeACallback an argument that happens to be a callable function; ITakeACallback indeed calls it.
Of course we can pass any callable function:
ITakeACallback(function(x) { return foo(x); });
This time we passed a function that accepts an argument, calls foo with that argument and returns the result. This is a roundabout way of calling foo directly, but the end result is the same.

Difference between 2 jquery binds

function runSomething () {
// some stuff happens
}
$(selector).bind('event', runSomething());
$(selector).bind('event', runSomething);
What's the difference between these 2 versions of the bind?
Here's a practical example:
http://jsbin.com/icajo/edit
Can somebody explain why works the way it does.
I'm trying to get multiple buttons to run the function upon the event, what should I do?
In first case you bind result of runSomething() call, in second - function itself.
update
#JSNewbie, run this and tell what you see in each alert.
function runSomething () {
return 3;
}
var a1 = runSomething();
var a2 = runSomething;
alert(a1);
alert(a2);
In javascript, passing a set of parameters to a function invokes the function, it gets evaluated to the functions return value.
var test = function() { return 1; } // Creates a new function that returns 1
alert(test.toString()); // => "function () { return 1; }"
alert(test().toString()); // => "1"
Even alert itself is just a variable that points to a function.
alert(alert); // => "function alert() { [native code] }"
So, if the first example, when calling runSomething(), it immediately evaluates that function, then passes the return value as a parameter to bind(). In your case, it evals the alert() as the page is loaded, then passes undefined to bind()
In your second example, using the variable runSomething the function itself is passed to bind(). Bind then uses that function only when the event has been raised.
To really blow your mind, you could have function that returns a function, then evaluating the function (like in your first example) is correct... For example
var counter = 0;
function GenerateNext() {
counter++;
return new Function("alert(" + counter + ")");
}
a = GenerateNext();
b = GenerateNext();
b() // will alert 2
a() // will alert 1
$(selector).bind('event', GenerateNext()); // alert 3
$(selector).bind('event', a); // alert 1
$(selector).bind('event', b); // alert 2
It just all depends on what you are trying to do; pass the function itself, or pass the return value of the function.
In the first line the function runSomething is executed within the bind statement, and that what it returns is bound to the event, for example if your runSomething function returns another function then that function is bound, and will be executed upon the event.
On the second line the runSomething function is not executed at that line, and is only only execute when "event" happens.
In javascript functions are treated as variables. Adding the "()" will call the function, and pass the result of the function (which could be 'undefined' if the function returns nothing). The second is the proper way of using the bind method, because it gives a handle to the function to call when the event is triggered.
$(selector).bind('event', 'runSomething()'); (notice the extra quotes around 'runSomething()')
run the function runSomething() when the event is received.
$(selector).bind('event', runSomething);
sets the function runSomething() as the callback function for the event, which means it will receive whatever parameters are included in the event, often this is useful for currentTarget (so you can use the same event on many buttons) or to get specific information from the event (mousemove returns the X,Y location of the mouse as it is triggered).
So if you needed to access the event object that is returned when the event is triggered, the first version wouldn't work properly.
function runSomething(event){
console.log(event); // this would show the event object if the second code is used.
}

Categories

Resources