As a definition said The void operator evaluates the given expression and then returns undefined.
so in this code
void function test() {
console.log('test function executed');
};
if we call it like test() , then should console.log('test function executed'); evaluated first then after finishing return undefined ? , rather than returning undefined only ? like this one
void function iife() {
console.log('iife is executed');
}();
If we go over to this operator precedence table, we see that function calls () have a precedence of 17, while the void operator only has a precedence of of 14 (same as typeof, delete, and await). Because of this, the following code
void function iife() {
console.log('iife is executed');
}();
is actually treated like
void (function iife() {
console.log('iife is executed');
}());
If you want the code to error then you need to use parentheses:
// Cannot call 'undefined' as a function
(void function iife() {
console.log('iife is executed');
})();
These are two different expressions:
one creates a function
the other one calls the function
You can see that void works correctly with creating a function here:
const x = function test() {
console.log('test function executed');
};
console.log(x) // function
With void:
const x = void function test() {
console.log('test function executed');
};
console.log(x) // undefined
If you want the function call to return undefined, you have to use void when calling the function
function test() {
return 10
}
const x = void test()
console.log(x)
So, void operator evaluates the expression that follows it, and then returns undefined.
In the case of test() function, as I said, it does evaluate the expression, which is a function expression:
void function test() {
console.log('test function executed');
};
So, you ask, why isn't the body executed? Because function expressions do not run the body. They just create the function somewhere in memory. The body is only run when the function is actually called.
Now, you call the function with test() and it throws:
Error: test is not defined
Why? Because the name of the function expression's scope is limited to the function body, not outer scope, as described here.
From the referenced article:
If you want to refer to the current function inside the function body, you need to create a named function expression. This name is then local only to the function body (scope).
In a nutshell, using void like above is kind of useless. It's just there for demonstration purpose and understanding how it works.
Related
can anyone explain to me what is JS doing here? Can anybody explain what is going on here in terms of type coercion, IIFE, and closures?
Function.prototype.toString = (
function() {
const toStringFnRef = Function.prototype.toString;
return function() {
return `start:${toStringFnRef.call(this)}end`;
}
}
)();
console.log(1 + function x() { alert('hi') });
//output: "1start:function x() { alert('hi') }end"
The IIFE is being used to create a local scope where the variable toStringFnRef contains the original value of Function.prototype.toString. Then it redefines this with a function that calls the original function and wraps the result in start: and end.
This could also be done using a lexical block (in ES6 most IIFEs can be refactored like this):
{
const toStringFnRef = Function.prototype.toString;
Function.prototype.toString = function() {
return `start:${toStringFnRef.call(this)}end`;
}
}
When you do 1 + function x() { alert('hi') } it converts both 1 and the function to strings so it can concatenate them. So this calls your redefined Function.prototype.toString(), which surrounds the normal string of the function with those wrappers. This is then concatenated with 1.
The context:
I am reading the book You Don't Know JS: Up & Going, Chapter 2: Into JavaScript. In the Polyfilling section, the author gives the following example:
if (!Number.isNaN) {
Number.isNaN = function isNaN(x) {
return x !== x;
};
}
So, what is being done here is creating a polyfill so that the ES6 method Number.isNaN can run in older browsers (ie, pre-ES6 versions). As I expected, he makes use of the older isNaN method. The former method is actually meant to deprecate the latter by design.
The question:
Why is isNaN being used as the identifier of the named function expression? I would have expected it to be used in the body somehow. Why? Because all of the identifiers usually seen in examples around the web, when comparing function expressions vs function declarations take the following form:
Function declaration:
function foo() {
// ..
}
Function expression:
var foo = function bar() {
// ..
};
So in this example bar is being defined within the brackets after the 'bar()' string. So why use 'isNaN' above when isNaN is an already defined function within JavaScript? Are we actually overwriting it for the purpose of the polyfill? What am I missing/misunderstanding here?
When you have a named function in an expression, that value is not hoisted but is saved in expression scope. So original value is not changed.
Sample
function bar(){
console.log("In Bar")
}
var foo = function bar(){
console.log("In Foo")
}
bar();
foo();
Why should you use it?
In case of exception, that will help you in debug. An anonymous function will not show any name in stack trace and if you have say 4-5 anonymous functions in 1 function, it becomes difficult as to which one failed. Having a named functions makes it little simple.
var bar = function Test() {
(function() {
(function() {
(function() {
throw new Error("I have no Name2")
})()
})()
})()
}
var foo = function Test() {
(function inFoo1() {
(function inFoo2() {
(function inFoo3() {
throw new Error("I have no Name2")
})()
})()
})();
}
function init() {
try {
foo();
} catch (ex) {
console.log(ex.stack)
}
try {
bar();
} catch (ex) {
console.log(ex.stack)
}
}
function start() {
init();
}
start();
You can also refer to Why using named function expressions? for more information.
If jsCode is:
function() {
return "test"
}
I can do:
String js = "(" + jsCode + ") ();"
mWebView.evaluateJavascript(js, new ValueCallback<String>() {
#Override
public void onReceiveValue(String s) {
Log.d("return value: ", s); // Returns the value from the function
}
});
to run the javascript code and get "test" as a value back in Java
But what if I need more complex javascript code, for example:
function() {
return test();
}
function test() {
return "test";
}
, which defines a function test() and calls it;
Passing this javascript code to webview's evaluateJavascript gives error: "Uncaught SyntaxError: Unexpected token function", source: (1)
The reason for this problem is that this syntax is invalid:
(function() {
return test();
}
function test() {
return "test";
})();
This is because the wrapping brackets attempts to run the internal code as a single function, which hopefully you can see is clearly not a single function. Instead you need to treat the outer function like a container that internalises other functions and variables you need. For example, this should work:
(function(){
function test(){
return 'hello';
}
return test();
})();
These wrapping containers are called Immediately invoked function expressions
JavaScript allows this:
function outside() {
inside();
return 44;
function inside() {
console.log("inside");
}
}
When outside is called the output is:
inside
44
Why does this work and why doesn't it work for other statements like the one below:
function outside() {
return 44;
console.log("inside");
}
which just prints 44.
What you see is the effect of hoisting. When a function is about to be executed, all the variable and function declarations are evaluated first, before the function is really executed. Thus your first function is equivalent to
function outside() {
function inside() {
console.log("inside");
}
inside();
return 44;
}
Details can be found in the specification, 10.4.3 Entering Function Code and 10.5 Declaration Binding Instantiation.
Why does JavaScript allow function declarations after the return statement?
Why the language is defined like this can probably only be answered by Brendan Eich.
Because the file is parsed first and function definitions are read at that time. You are calling the function before you return, so that works just fine. Most programming languages allow you to define functions after calling them, because they all work in two steps: parsing and execution.
In the first case first the function inside is executed and then it comes to return..so it returns 44..
But in the second case the outside function first encounters return which means to exit from that function no matter what is return below... so it only prints 44
function outside() {
inside(); //calling inside();
return 44;
function inside() {
console.log("inside");
}
}
but here
function outside() {
return 44;
console.log("inside");
}
you are just returning not calling inside() at all.
Function declaration:
function myName() {
}
Function Expression:
var myName = function() {
};
These are very different, the function declaration (1) is defined when the Javascript is parsed, and not when it is executed. whereas the function expression (2) is defined when the Javascript is executed.
So technically it is not being defined after the return statement.
At least this is how I understand it.
I use only jQuery for writing JavaScript code. One thing that confuses me is these two approaches of writing functions,
First approach
vote = function (action,feedbackId,responseDiv)
{
alert('hi');
return feedbackId;
}
Second approach
function vote(action, feedbackId,responseDiv)
{
alert('hi');
return feedbackId;
}
What is the difference between the two and why should one use the first approach or the second approach?
The first is a function expression assigned to the vote variable, the second is a function declaration.
The main difference is that function statements are evaluated at parse time, they are available before its declaration at runtime.
See also:
Named function expressions demystified (article)
Explain JavaScript’s encapsulated anonymous function syntax
function myFunction() {}
...is called a "function declaration".
var myFunction = function() {};
...is called a "function expression".
They're very similar; however:
The function declaration can be declared after it is referenced, whereas the function expression must be declared before it is referenced:
// OK
myFunction();
function myFunction() {}
// Error
myFunction();
var myFunction = function() {};
Since a function expression is a statement, it should be followed by a semi-colon.
See Function constructor vs. function declaration vs. function expression at the Mozilla Developer Centre for more information.
The function declaration syntax cannot be used within a block statement.
Legal:
function a() {
function b() {
}
}
Illegal:
function a() {
if (c) {
function b() {
}
}
}
You can do this though:
function a() {
var b;
if (c) {
b = function() {
};
}
}
The first one is a function expression,
var calculateSum = function(a, b) { return a + b; }
alert(calculateSum(5, 5)); // Alerts 10
The second one is a plain function declaration.