Function returning function and no reference - javascript

My question is about this function:
function d() {
function e() {
alert('E');
}
return e;
}
d()();//alerts 'E'
When function d is called first time function e is returned, however, nothing holds reference to the returned value( function e in this case), and this returned value should be lost. So, how does this d()() work ? It's not a closure according to my understanding. Thank you !

The call to d (which is d() in that last line) returns e, and then the last () immediately calls that function.
Consider
function n() { return 5; }
console.log(n() + 1); // 6
Nothing holds the return value from the call to n(), and yet the return value can be used in the addition operation. The return value from the call to d() can similarly be used as a reference to a function in a function call expression, which is exactly what happens in your code.
To put it another way, d() returns a reference to a function (e). In order to call a function, all you need is a reference to a function taken from somewhere, and a parenthesized argument list. That's what d()() gives you.

You don't need a named reference to a function in order to use it. You can apply an operator to the result of any expression in place, and the () function call is just another operator.
So it's little different from performing addition on the result of a function call.
function returnTwo() {
return 2;
}
console.log(returnTwo() + 40);
Here we don't store the result of returnTwo(), but we can still use it as the left operand of the + operator. So with the function call in your example, you're doing the same thing.

function d() {
function e() {
alert('E');
}
return e;
}
d()();
//alerts 'E'
It doesn't need a reference because it is explicitly transformed into the returned value. Unless stored, the result of a JavaScript Expression( a sequence of interpreted variables, functions, and/or operations that returns a value ) will be fully evaluated and then removed from memory. The key is that it has to be fully evaluated. You can almost think of functional execution as horizontal Russian Nesting Dolls. The JavaScript expression is:
d()();
So it begins left-to-right with:
d()
which is executed and returns:
function e() { ... }
which turns the line into:
function e() { ... }()
which is then executed, alerts, and returns:
//nothing
The full Expression is completed. There is nothing left for it to do. The reference isn't stored anywhere and immediately after this expression is resolved everything that was returned from its evaluations is thrown away.

Related

Immediately invoked function expression without using grouping operator

I'm trying to immediately invoke a function without using IIFE pattern (enclosing a function definition inside parentheses). Here I see two scenarios:
When a function declaration is invoked immediately: gives SyntaxError.
When a function expression is invoked immediately: executes successfully.
Example 1: gives SyntaxError
//gives `SyntaxError`
function() {
console.log('Inside the function');
}();
Example 2: Executes without any error
// Executes without any error
var x = function() {console.log('Inside the function')}(); // Inside the function
So, I have these doubts:
With this approach, why does it give an error for function declaration but not for function expression?
Is there a way we can immediately invoke a function declaration without using IIFE pattern?
In your code you don't have name for the function that's the reason for syntax error. Even if you would had name it would have thrown error.
function func(){
console.log('x')
}();
The reason is the function declaration doesn't return the values of the function however when you wrap function declaration inside () it forces it be a function expression which returns a value.
In the second example the function() {console.log('Inside the function')} is considered expression because it's on RightHandSide. So it executes without an error.
Is there a way we can immediately invoke a function declaration without using IIFE pattern
You can use + which will make function declaration an expression.
+function(){
console.log('done')
}()
If you don't want to use + and () you can use new keyword
new function(){
console.log('done')
}
Extra
A very interesting question is asked by #cat in the comments. I try to answer it.There are three cases
+function(){} //returns NaN
(+function(){return 5})() //VM140:1 Uncaught TypeError: (+(intermediate value)) is not a function
+function(){return 5}() //5
+function(){} returns NaN
+ acts as Unary Plus here which parses the value next to it to number. As Number(function(){}) returns NaN so it also returns NaN
(+function(){return 5;})() returns Error
Usually IIFE are created using (). () are used to make a function declaration an expression + is short way for that. Now +function(){} is already an expression which returns NaN. So calling NaN will return error. The code is same as
Number(function(){})()
+function(){return 5;}() returns 5
In the above line + is used to make a statement an expression. In the above example first function is called then + is used on it to convert it to number. So the above line is same as
Number(function(){return 5}())
In the proof of statement "+ runs on after the function is called" Consider the below snippet
console.log(typeof +function(){return '5'}());
So in the above snippet you can see the returned value is string '5' but is converted to number because of +
A function declaration, like
function foo() {
}
defines (and hoists) the variable name foo as a function in the current scope. A function declaration doesn't evaluate to a value; it just does something, a bit like an if does something (rather than evaluate to a value).
You can only invoke values which are functions, eg
<somevalue>()
where somevalue is a variable name that refers to a function.
Note that function declarations require function names, because otherwise there's no variable name to assign the function to - your original
//gives `SyntaxError`
function() {
console.log('Inside the function');
}();
throws not because of the () at the end, but because of the lack of a name.
You can put parentheses at the end of a function declaration, as long as there's something inside the parentheses - but these parentheses do not call the function, they evaluate to a value:
function x() {
console.log('Inside the function');
}(console.log('some expression inside parentheses'));
The interpreter sees these as two separate statements, like
function x() {
console.log('Inside the function');
}
// completely separate:
(console.log('some expression inside parentheses'));
The inside of the parentheses gets evaluated and then discarded, since it doesn't get assigned to anything.
(Empty parentheses are forbidden because they can't be evaluated to a value, similar to how const foo = () is forbidden)
The E in IIFE stands for expression, and without the wrapping parenthesis your function is not evaluated as an expression thus the syntax error.
creating an expression is a way of tricking the interpreter and be able to invoke the function immediatly
(function() {
console.log('Inside the function');
})();
In your example you have a function statement followed by the grouping operator, but it's syntactically incorrect for two reasons, first it doesn't have a name, and second because the grouping operator must have an expression inside it, infact if you add a valid one the error will disappear, still you won't obtain your desired result.
function foo() {
console.log('Inside the function');
}();
function foo() {
console.log('Inside the function');
}(1+2);
In order to invoke something, it has to be a function value, a declaration just declares a name, and does not evaluate to the function value itself, hence you cannot invoke it.
A declaration cannot be invoked for the above reason. You have to end up with an expression somehow, either through assignment or grouping (IIFE). So that is a no.
If you give us more context on why you would want to do that, maybe we can help with suggestions.
Not sure why you would want to do it, but:
Is there a way we can immediately invoke a function declaration without using IIFE pattern?
Well, if for function declaration you mean using the keyword function as in:
function name() { return this.name; }
As far as I know, no. You need the extra parentheses to tell the runtime not to assign the function to a name variable, if I understand this stuff right.
Now, what you actually can do is to use Function as in:
new Function('console.log("ey there")')();
Which will execute the console.log code. No need for IIFE here. But I don't see how this could be better than an IIFE.
you can call in either below ways -
~function(){console.log("hi")}()
!function(){console.log("hi")}()
+function(){console.log("hi")}()
-function(){console.log("hi")}()
(function(){console.log("hi")}());
var i = function(){console.log("hi")}();
true && function(){ console.log("hi") }();
0, function(){ console.log("hi") }();
new function(){ console.log("hi") }
new function(){ console.log("hi") }()

Function expressions vs function declarations: return value

In a Udacity lesson the difference between function expressions and declarations is explained as follows:
A function declaration defines a function and does not require a
variable to be assigned to it. It simply declares a function, and
doesn't itself return a value ... On the other hand, a function
expression does return a value.
This is confusing; to my knowledge, when both function expressions and function declarations include a return statement, both return a value.
If I understand correctly, the difference with respect to return value is that in a function expression, if a value is changed in the first call of the function, in a subsequent call the updated value would be preserved—whereas if the function were not stored in a variable, the return value would be erased when the function is finished executing. Am I missing something, and is the statement from the lesson accurate?
Note: My question is different from the one marked as a duplicate. In that question it asks what the reasons for using one over the other, but return value is not mentioned in the question or explained in its answers.
To understand what this really is about, we need to dig into the JavaScript grammar:
In ECMAScript a script consists of Statements and Declarations. A Statement can be (amongst others) an ExpressionStatement. Note that ExpressionStatement is explicitly defined as:
ExpressionStatement[Yield, Await]:
[lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }]
Expression[+In, ?Yield, ?Await];
This looks really cumbersome, but what it says is that an ExpressionStatement cannot possibly start with the keyword function. So if you just write:
function a() {}
This can never be interpreted as an expression although in other circumstances like
const a = function a() {}
it is an expression. (The right hand side of an assignment operation always must be an expression.)
Now, only expressions evaluate a value, statements do not. This is all the text you quote is saying in a hard to understand way.
A function declaration defines a function and does not require a variable to be assigned to it:
True but redundant. A declaration cannot occur at the right hand-side of an assignment.
It simply declares a function, and doesn't itself return a value ...
Yeah, statements do not evaluate to ("return") a value.
On the other hand, a function expression does return a value.
Sure, like any expression.
See https://www.ecma-international.org/ecma-262/8.0/#prod-StatementList
On the other hand, a function expression does return a value.
This is confusing
Yes indeed. What they actually meant was a function expression evaluates to a (function) value - in contrast to a declaration, which is not an expression but a statement and doesn't evaluate to anything. It has nothing do with the value that the function might return from a call.
The definition isn't talking about the function returning a value, it is talking on how one way of creating a function returns a value (which is the function expression) and another just declares a function (a function declaration).
To help you clarify things, you should understand first what an expression is:
An expression is any valid unit of code that resolves to a value.
One example of an expression would be x = 5, which evaluates to 5.
Another example would be 3 + 2, which also evaluates to 5.
In other words, we could say that both expressions above return a value of 5.
A function expression is just an expression that returns (evaluates to) a function:
// expression
const whatever = function expression() {}
// ^^^^^^^^^^^^^^^^^^^^^^^^ this is the function expression in an assignment statement
A function declaration is not an expression but a statement.
It doesn't need to evaluate to a value. It is just immediately declared:
// declaration
function example() {}
How a function is created (via a declaration or an expression) doesn't affect what the function can return - that capability is the same in both cases.
You are right to say that example is confusing.
Maybe it helps if you think of "return value" in the context of an interpreter? By that I mean, imagine if you were parsing Javascript yourself (as if you were Chrome's v8).
The declaration would just define a new function type and it'd be available for use after declaration.
// declare a function named Declaration
function Declaration() { // stuff }
Now imagine it is instead an expression getting evaluated.
// named function expression
var foo = function FooFunc() { // do stuff }
// anonymous function expression
var foo = function () { // do stuff }
// a self-invoking anonymous function expression (example of a non-variable assingment
// The parentheses make it self-invoking and not a declaration.
(function foo() { console.log('foo'); })() // outputs 'foo' when parsed
+function foo() { console.log('foo'); }(); // same as above
!function foo() { console.log('foo'); }(); // same as above
-function foo() { console.log('foo'); }(); // same as above
~function foo() { console.log('foo'); }(); // same as above
First, sees if an assignment (or self-execution) is going to take place. Do this by checking for const or var or (.
Let's suppose the expression is the variable assignment var foo = function fooFunc() {}.
In this case, the interpreter knows that while you'r defining fooFunc, you also want the result of the definition -- the fooFunc function -- to be the value of foo and so there is a "return value" -- the fooFunc function object -- that needs to be assigned.
This can be difficult to learn at first, but lets try a different approach.
They are not talking about the returned value of a function call, its about the value of the expression (as well explained in the other answers).
You can use the console in the Chrome's Developer Tools to see what each expreassion evaluates to, for example: if you input 10 in the console, this expression will return 10
> 10
< 10
And so on...
> 10 + 5
< 15
> 'Hello world!'
< "Hello world!"
Assigning a value to an variable (not with var, const or let) returns the variable new value, so you can see this in the console:
> n = 10
< 10
> var foo = (n = 10) // also `var foo = n = 10` or `foo = n = 10`
< undefined
> foo
< 10
> n
< 10
> (obj = {}).foo = 'bar'
< "bar"
> obj
< {foo: "bar"}
When we are talking about functions, the declaration of it does not return any value, but a function expression returns a reference to the function created, thats why you can assign it to a variable.
> function foo() { }
< undefined
> (function() { })
< ƒ () { }
Thats why you can do things like:
> (function() { return 'it works!' })()
< "it works!"
> myFunc = function() { return 'also works!' }
< ƒ () { return 'also works!' }
> myFunc()
< "also works!"
Hope this help you undertand. :)

Passing "extra" arguments to a function stored in a variable - Javascript

I'm new to Javascript, I'm self-teaching, so this might be an obvious area, but no matter how I phrase the question I can't really seem to get my head around this one issue. At the moment I'm reading through http://eloquentjavascript.net/chapter6.html (which was on mozilla's MDN). I've come across this a couple of times now, I would just like a simple break down if possible.
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
show(isNotNaN(NaN));
I don't understand how at the very last step isNotNaN (a variable) is passing an 'extra argument' (NaN) to the function stored in isNotNaN (negate(isNaN). "show(isNotNaN(NaN));"
I came across this same problem when the concept of enclosure was trying to be explained. But I don't get where this argument "NaN" is going in the above function, as it seems to me like the last statement ends up something like:
show(negate(isNaN, NaN));
I would be happy to provide more details. This concept of passing an extra argument to a variable already holding a function with an argument confuses the hell out of me!
There's no "extra" argument. The negate() function itself returns a function defined as a function expression, which can then be called with any number of original (not extra) arguments passed. A closure is used for the returned function to keep a reference to isNaN as func.
var isNotNaN = negate(isNaN);
At this point, isNotNaN contains a reference to the function
function(x) {
return !func(x);
};
Again, func here refers to the isNaN argument passed to the negate function, which is the immediate parent in the scope chain. The result is similar, but not the same as
var isNotNaN = function (x) {
return !isNaN(x);
};
The reason it is not the same is, if we change the value of isNaN, the behaviour of this function will change. In the example you posted, however, the value of func is equal to the original value of isNaN and cannot be changed by anything outside of its scope thanks to the closure.
Essentially, you can pass in any function and get a new function that returns the negated result of the original function in return. For example:
var isNotArray = negate(Array.isArray);
isNotArray(12);
//-> true
In fact, negate(isNaN) simply return a function to the variable isNotNaN. This function take a parameter (named x in your case), then execute the function isNaN on the parameter before negating it and returning the result.
Perhaps this example can clear some things out for you regarding closures:
function foo(x){
function bar(y){
return x+y;
}
return bar;
}
var fooRef = foo(1); // fooRef references foo() with x set to 1
console.log(fooRef(2), foo(1)(2)); // 3, 3
http://jsfiddle.net/ePwy8/

Code inside block is wrapped inside parens. Why?

I came across this code and don't understand why the code within the block is wrapped in the parens like an auto-executing function.
function foo(a,b) {
var b = b || window,
a = a.replace(/^\s*<!(?:\[CDATA\[|\-\-)/, "/*$0*/");
if (a && /\S/.test(a)) {
(b.execScript || function (a) {
b["eval"].call(b, a)
})(a);
}
}
The first parameter is the text from a script tag. The only part I don't get is why the script eval is wrapped in parens.
I assume you are talking about this part:
(b.execScript || function (a) {
b["eval"].call(b, a)
})(a);
This is short form of writing:
if (b.execScript) {
b.execScript(a);
}
else {
b["eval"].call(b, a);
}
I.e. execute b.execScript if it is defined, otherwise call b["eval"].call(b, a).
The purpose of the grouping operator is to evaluate ... || ... before the function call, i.e. whatever the result of the grouping operator is, it is treated as function and called by passing a to it.
It looks like the code could be simplified to
(b.execScript || b["eval"])(a);
Though if explicitly setting this to b is necessary, then the function expression is necessary as well, to have two functions that only accept one argument, a.
(b.execScript || function (a) {
b["eval"].call(b, a)
})(a)
This is wrapped in parens because the || statement needs to be evaluated to determine what function to run before being passed an argument.
This code calls b.execScript with argument a if b.execScript exists and is truthy. Otherwise it defines a new function and passes a as an argument to that.
The parens wrap is to make sure that the || statement is evaluated before the function is executed. Without it the logic would go basically, if b.exec doesn't exist, evaluate to the value of the custom function, if it does, evaluate to b.exec.
So with the parens the logic is equivalent to:
if(b.execScript){
b.execScript(a)
}
else{
function (a) {
b["eval"].call(b, a)
})(a)
}
without it, its equivalent to
if(!b.execScript){
function (a) {
b["eval"].call(b, a)
})(a)
}
It's parenthesized because the || operator binds more loosely than the function invocation operator (). Without the enclosing parentheses, the expression would be evaluated as if it were written:
b.execScript || (function (a) { b["eval"].call(b, a); })(a)
That is, it'd be either the plain value of b.execScript or the value of invoking that function. What the author wanted was invoke either the value of b.execScript (which would presumably be a function) or that little anonymous function.
Because of the (a) afterwards. The expression:
(b.execScript || function (a) {
b["eval"].call(b, a)
})
returns a closure which is then executed with a passed as a parameter.
The parenthetical expression returns either the result of b.execScript, or a new function. In either case, the result is then invoked with a as a parameter. The parens make sure the interpreter evaluates the || before the invocation.
why the code within the block is wrapped in the parens like an auto-executing function.
Because that particular part of the code is an auto-executing function:
(b.execScript || function (a) {
b["eval"].call(b, a)
})(a);
Here, the variable b references the execution container, e.g. window, and a contains JavaScript code that needs to be executed.
Since some browsers support execScript() while some only support eval(), the code supports them both by testing this browser feature like so:
var tmp = b.execScript || function (a) {
b["eval"].call(b, a)
};
Here, tmp is a function that takes a single parameter a and executes the code within; if execScript is not available, a small helper function is used instead. And then it's called like this:
tmp.call(b, a);
The first parameter to .call() defines what this refers to when tmp is called; the second parameter becomes the first parameter of tmp.

When is "this" evaluated?

For the following piece of code
a.b = function c(){
return function e(){
return this;
};
};
d = a.b();
What will the value of d() be? This might not be a very good example, but I am just confused about what "this" will refer to.
Thanks,
Seeing as d will now equal a FUNCTION, "this" will be evaluated to whatever function calls it. It hasn't actually been evaluated yet.
At the end of execution, d='function e() { return this; }', so the moment you execute d() is when this will be evaluated.
From your code d is not the same as the "this". d will be a the function e, since you are setting d to be return value of the function call a.b() which returns a function, so
d = function e(){
return this;
}
Now the value of this depends upon how you call this function d. this will be evaluated when this function is called. If you just call it like d() this will be the global Window Object.
and lets say if I have
obj ={foo:1, bar:2};
and I call like this
d.call( obj )
this will be the object obj. the call() method is used to call a function on any object, the passed object behaves as this inside that function.
I know Javascript this is really confusing and it isn't easy to get your head around it.
May be this can help http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
this is an implicit parameter to all functions.
See apply and call
If you know python, this is just like self, but not explicitly written and always there
this is normally the caller of a function
$('.image').each(function(index){
alert($(this).attr('href'));
}
I think a.b() will return a
see http://remysharp.com/2007/04/12/jquerys-this-demystified/
this is a reference to the object on which method was called.
d() is similar window.d() (if there is no with instruction)
Assuming d() was called immediately after the last line of your snippet d() will return the global object: window if you're in a browser.
However both of these are true:
d.call(a) === a;
d.call(a.b.prototype) === a.b.prototype;
which is to say that this is defined by what is passed in as the first argument to call.

Categories

Resources