javascript function hoisting does not works - javascript

function test(flag){
if (flag) {
return function test1(){console.log(1)}
}else{
return function test1(){console.log(2)}
}
}
test(true)()
test()()
it log 1 and 2,why not double 2?
how does this works
my english is not very good, thank you
this also works with 1 and 2
function test(flag){
if (flag) {
function test1(){console.log(1)}
return test1
}else{
function test1(){console.log(2)}
return test1
}
}
test(true)()
test()()

The function in this line:
return function test1(){console.log(2)}
Is not a function declaration. It is a named function expression, because it is part of a statement.
Function expressions are not hoisted. Only function declarations are hoisted, like this:
function test(){
return test1;
function test1() { console.log(1); }
function test1() { console.log(2); }
}
test()();
Edit: Regarding the question you added after the fact, function declarations inside conditional expressions have undefined behavior and you can see different results depending on your JavaScript engine. Functions inside if-else statements may not be hoisted to the top of the scope, and you should not put function declarations inside conditional expressions. More about this

In the first call test(true)() it goes through:
if (flag) {
return function test1(){console.log(1)}
}
because the flag has value true.
In the second call test()() it goes through the else path:
else{
return function test1(){console.log(2)}
}
because in that instance value of flag is undefined and it evaluates as false.
You can get an idea about truthy and falsy using these links.
Hope you got the idea here. Please let me know if you have any questions.

Related

why it is returning two values instead of one , while using || in return statement?

Following is my pseudo code:
function main() {
return one() || two();
}
function one() {
console.log("one");
}
function two() {
console.log("two");
}
main();
I recently studied that in the return statement if one and two functions are variables containing any values then one is returned unless it is false or null or undefined but what about while using functions in this example?
can someone help me...
1) You're not returning any values. You're writing to the console so what is returned is undefined
2) undefined is false so the || evaluates both sides.
The return value of your one() and two() functions are undefined, as those are just logging the strings to the console, but not returning those.
Try this:
function main() {
return one() || two();
}
function one() {
console.log("one");
return "one";
}
function two() {
console.log("two");
return "two";
}
main();
The "value" of both the one and two function calls are the undefined value, because they do not return any other value.
So it would seem that you're really asking why both functions are printing to the console. This is because the act of printing to the console does not establish the "truthy" or "falsey" state of the functions. This is determined only by the function calls' return value, as noted above.

How do I call a function within an IIFE expression

Just started out learning js and using the book Javascirpt an Absolute Beginner's Guide. Question is from an example in the book:
var awesomeSauce = (
function () {     
var secretCode = "Zorb!";
     function privateCheckCode(code) {
if (secretCode == code) {
alert("You are awesome!");  
} else {
alert("Try again!");  
}     
}
    // the public method we want to return     
return {
checkCode: privateCheckCode     
};
})();
Question is how do I go about to call this code?
awesomeSauce("Zorg!");
doesnt work and neither does
awesomeSauce().privateCheckCode("Zorg!");
awesomeSauce.checkCode("Zorg!");
The IIFE returns an object with the checkCode property, that property is the (private) function.
The point of the IIFE is that this scopes the variables and functions within, so that they are not accessible from outside (e.g. privateCheckCode and secretCode exist only inside the IIFE).
Think of the returned object as an "export" of selected values or functionality.
var awesomeSauce = (
function () {
var secretCode = "Zorb!";
function privateCheckCode(code) {
if (secretCode == code) {
alert("You are awesome!");
} else {
alert("Try again!");
}
}
// the public method we want to return
return (
privateCheckCode
);
})();
awesomeSauce('Zorb!')
hey i don't know much but i happened to solve this: return statement return an expression not a code block. just go through the code i guess you will understand
Agree with Lucero's answer
1) The IIFE gets executed
2) result of the execution gets assigned to awesomeSauce
So what is the result of execution ?
It is whatever the function returned, below code
return {
checkCode: privateCheckCode
};
In this case, it returns an object with a property named "checkCode" which refers to inner function "privateCheckCode".
In short, it becomes,
awesomeSauce = {
checkCode: privateCheckCode
};
Therefore, you can call your function like this awesomeSauce.checkCode("Zorb!");
You can call it with console.log(awesomeSauce.checkCode('Zorb!'));
as the iife returns an object which has checkCode key and the privateCheckCode as the value.

In Javascript, is it possible to stop outer function execution from inner function?

Is it possible to break out of an outer function from its inner function?
(function one(){
var foo = (function two(){
if(true){
return true; //all good
}else{
//how can we break function one here?
})();
//extra statements only executed if foo is true
})();
No such thing as "return return" right? :P
UPDATE
Thanks all - as I suspected the "return return" functionality I was looking for is not possible. But with your input/tips I reworked my code and used a try/catch block. There a many ways to skin a cat in JS!
return only applies from within the function it's used.
What you can do is make two() return a boolean.
Than evaluate two() inside an if statement inside one()
function two() {
// Some logic here...
var isError = true; // sometimes is false :)
// Internals
if (isError) {
console.log("Something is wrong");
}
// Finally return a boolean
return isError;
}
(function one(){
// `two()` returns a boolean, true if there's an error.
// `return` will stop furthere execution of `one()`
if( two() ) return;
console.log("This will not log if there was an error")
})();
In your example code, it would be best for the outer function to test foo, but in more complex code, exceptions might be appropriate:
;(function() {
var foo = (function() { return true })()
if (!foo) return;
console.log('reached because foo was true')
})()
;(function() {
try {
;(function() {
var foo = (function() { throw new Error('fail') })()
/* only reached if an error wasn't thrown */
})()
}
catch (error) {
console.log('Something went wrong: ' + error)
}
})()
Output:
reached because foo was true
Something went wrong: Error: fail
This desire might appear more often in JavaScript than in comparable languages because JavaScript's only way to provide scope is with a function body, and you have fewer control-flow options across function boundaries. But if you're using a self-executed function purely to provide a scope, and not keeping the function around to close over the variables, then just don't do that when you run into control-flow situations like this.
The general idea of a function is that it will return a data type for the single function of which it resides. Return is just a language feature used to implement this idea of giving back data from the function. And so the notion of performing a return-return cannot be applied.
But in this paradigm, the problem you are solving is more related to Flow of Control. The solution you choose should be based on how you can most clearly express the idea in your code.
Depending on the reason you ask this question, if you are being challenged by a certain piece of logic in your application, and aren't just asking a technical question about the language, I would recommend posting a code sample which allows us to understand the intention of your goal. Since this is the key factor to choosing the best solution.
Of course you may implement a solution in all sorts of ways. Exceptions, statefulness, or functional solutions. But you need to choose the right tool for the job.
//how can we break function one here?
return false ?
var div = document.querySelector("div");
var buttons = document.querySelectorAll("button");
var process = function process(value) {
return (function one(val) {
var foo = (function two(bool) {
if (bool) {
return true; //all good
} else {
return false //how can we break function one here?
}
})(val);
//extra statements only executed if foo is true
// if `foo` : `true` do stuff
if (foo) alert(foo);
// return `foo`
return foo
})(value)
};
var fn = function(e) {
div.innerHTML = process(e.target.textContent === "false" ? false : true);
}
buttons[0].onclick = fn;
buttons[1].onclick = fn;
<button>true</button>
<button>false</button>
<div></div>

Please explain the behavior of this code in javascript

I have wrote a code in javascript like
function onClic(){
var i = 0;
if ( i==2 ){
var m = function(){
return 1;
}
}
else {
var m = function(){
return 2;
}
}
alert(m());
}
the alert shows 2;
can you please explain me the behavior in this statement i.e. Why am I able to access m outside the If statement when I declared it inside If statement scope.
Also why is this working as ECMAScipt 5 specifies that we donot put the function declaration inside IF-ElSE block.
Why am I able to access m outside the If statement when I declared it inside If statement scope.
Because JavaScript (ES5 at least, has only function scope, not block scope. The if statement does not create scope. Your code is equivalent to:
function onClic(){
var i = 0;
var m; // m is "hoisted"
if ( i==2 ){
m = function(){
return 1;
}
}
else {
m = function(){
return 2;
}
}
alert(m());
}
Also why is this working as ECMAScipt 5 specifies that we donot put the function declaration inside IF-ElSE block.
Right, but what you have are function expression, not declarations. A function declaration is something like
function foo() { }
Function expressions can be put everywhere where an expression is valid to use.
While you are right that, according to the spec, function declarations cannot be used inside blocks, browser still allow it and actually produce different results. Run this in Firefox and Chrome:
function foo() {
alert(1);
}
if (false) {
function foo() {
alert(2);
}
}
foo();
However, this will change in ES6 where this behavior will be properly defined.
Your variable i is set to 0 at the start of your function. You never change it. You IF statement is testing if i is equal to 2; it isn't. So it jumps to the ELSE statement, and returns 2.
If you want it to do something, you never to change the value of i in some way that makes sense to the problem you are trying to solve.
function onClic(){
var i = 0;// set i=0
if ( i==2 ){ // so this condition always give false and control go to else statement
var m = function(){
return 1;
}
}
else {
var m = function(){
return 2;
}
}
alert(m());
Just saw what you were actually asking.
The variable is still inside the onClic() function so it is still in the local scope even though it is within an if statement.
First you are checking for value of variable i in your function
If condition check the value of i , if it is 2 it makes a function assignment to variable m the function returns 1
if value of i is not 2 it makes a function assignment to variable m the function returns 2
In the end you call m that return either 2 or 1.
my variable is inside the scope of If statement then how am I able to
get its value outside the scope in the last round
The answer is in js you dont have block level scope , you have either global scope or local scope. Here I is local varaible so it can be accessed any where in this function

Curly bracket with "return" keyword [duplicate]

This question already has answers here:
Why do results vary based on curly brace placement?
(6 answers)
Closed 9 years ago.
var calculator = function ()
{
function abc() { return (2+3); }
return {
addFun: abc
}
}();
var calcu = function () {
function abc() { return (3+4); }
return
{
addFun: abc
}
}();
$(document).ready(function () {
alert(calculator.addFun());
**alert(calcu.addFun());**
});
What is difference between calculator and calcu function? calcu function gives error when it execute.
Difference is only that curly bracket is next line in "calcu". It is work fine if I remove next and put curly bracket with "return" keyword.
Please explain why so?
It's being parsed as this:
return; // returns undefined
// a block:
{
addFun: abc // syntax error!
};
because of automatic semicolon insertion.
Change it to:
return {
addFun: abc
};
It's called automatic semicolon insertion:
When a continue, break, return, or throw token is encountered and a LineTerminator is encountered before the next token, a semicolon is automatically inserted after the continue, break, return, or throw token.
Since there's a newline right after your return statement, a semicolon is inserted automatically, turning your code into:
return;
{
addFun: abc
}
Return is a tricky keyword in JavaScript. In the first example, you are returning an anonymous object to the calculator function, and in the second example you are returning no values. JavaScript will interpret the second function like this:
var calcu = function() {
function abc() ...
return; // return undefined
{
addFun: abc
}
Notice the semi colon is interpreted after the return keyword and thus the calcu function will return nothing.
return
{
addFun: abc
}
This is wrong because JavaScript would execute return and will get out.
This should be
return {
addFun: abc
}
Have a look at linting tools such as jshint to avoid this and many other errors, here is it's output:
What happens is that this section:
return
{
addFun: abc
}
is being interpreted as two statements, a return void (the function returns void immediatelly) plus an object expression containing addFun that is not assigned to anything.

Categories