Why console.log() returned 'undefined'?

Why console.log() returned 'undefined'?

Understand why browser console behaves the way it does.

If you've spent some time exploring the browser console or are a beginner in web development like me, having used console.log() to debug your code in the browser console, you may have observed a peculiar behaviour of this common Javascript method.

The first value logged when you enter console.log('Hello World') will be 'Hello World'. Just like you expected it to? Hold On.

Now look at the following line, did you see a second returned value of 'undefined'?

Why is there a second value if all we asked for and expected was the value "Hello World"? Is something wrong with my browser or console? Nah! This is exactly how the browser console is expected to work. Let's dive into understanding this!

Tl;dr

  • The unexpected 'undefined' is due to the nature of REPL environments.

  • Keep Read-Eval-Print-Loop in mind, to understand how inputs entered are evaluated by REPL environments, like the console.

  • Expressions return a value to the console, not statements.

  • Functions return 'undefined' if a value is not explicitly returned.

What is a REPL?

The acronym REPL(say it, “REP-UL”) stands for Read-Eval-Print-Loop. Whether it is through ‘node’ for JavaScript or ‘python’ for Python, entering REPL provides you with a sandbox or a playground in layman's terms, to explore your code.

Exploration can include building/testing small code snippets or expressions to even observing how your functions are behaving before you can use them in your scripts. For those familiar with Linux, this is like your command-line tool and hence it is important to note that, it does not require file creation to write your code.

Check out Replit and CodeSandbox, some popular online playgrounds to run, test and even share your code.

Remember the BODMAS rule in mathematics? If you are familiar with that, REPL will start making sense to you. Let me explain!

Think of REPL(say it again, "REP-UL") as an interaction with your computer to:

  1. Read the user input(💻: hi, i want to know you)

  2. Evaluate your code

  3. Print any results(so you can see the computer's response)

  4. Loop back to step 1(💻: let's keep this conversation going)

To understand this interaction a little better:

//Example 1: 
4 * 3 % 6 // 0
//Example 2:
Math.pow(2,5) // 32

Look at the above code snippet. Your REPL will first read the above code using the language native to the REPL, Javascript in this case, since this is in a browser console. Note, language could be different but the rules of the interaction stay the same!

Now that it has read, it will evaluate lines that include operations. These operations could include arithmetic expressions, comparisons, data structure manipulations, etc. So here, line 1 would be evaluated and returns the result of the expression.

After all evaluations are performed, it will print the result returned from the evaluation. Hence, in Example 1 0 is printed to the console.

Finally, it looks to loop. No, it will not start a for or while statement now. Loop here means to go back to the state in which the computer is ready to accept more inputs. Yes, the computer does not want to end our interaction 🥺 . So in the above snippet, the console will continue to read, moving to Example 2.

Broke down the steps for you! Now like BODMAS, keep R-E-P-L in mind every time you read your code in the browser console.

The uncanny 'undefined'

Now that I have given you the context, let's address the elephant(undefined) in the room(my console, but ok). We will go through different cases to try to understand the console behaviour, keeping the R-E-P-L rule in mind.

Let's first start with the below statements.

//Example 3:
const greet = 'Hey Amit, welcome to my blog';// undefined
//Example 4:
const sum = 12 + 6;// undefined

Looks familiar? Why did they return undefined? Apply the R-E-P-L rule. The console reads line 1 and understands it to be a variable declaration. It is just a statement i.e one that does not return any value. If the evaluation does not result in a value, it will print undefined.

Okay... but Example 4 is an arithmetic operation right...? Well yes, 12+6 is an arithmetic expression, but does it return the result to REPL to print? No, it rather assigns the resultant output to the variable sum, making it just like the statement on line 1. Are things starting to make a little sense now?

//Example 5:
function sqr(a){
    let res = a * a;
};
//undefined

The above code snipped should be an easy follow-up. Quick, to call it just as Example 4? Well, you are not entirely wrong. In Javascript, every function is expected to return a value. If not, a default value of undefined will be returned. Ok, then let's explicitly ask it to return the resultant res of the expression.

//Example 5:
function sqr(a){
    let res = a * a;
    return res;
};
//undefined

😲Didn't we follow the syntax? How do you execute a function? A function does not execute after it is defined, it has to be explicitly called. In Example 5 function is only declared, we forgot to invoke it. In such a case, when REPL reads the function line by line, it treats it as a set of declared statements. Hence, when you hit ENTER, REPL prints undefined. Ok, let's fix this.

//Example 5:
function sqr(a){
    let res = a * a;
    return res;
};
//undefined
sqr(2);
//4

Lines 1-4 are read and it prints undefined first, as explained previously. But now that we have invoked the sqr() function, passing an argument to it, the return statement was evaluated and the output 4 is printed.

Now, you have a better idea of the scenarios that lead to the uncanny undefined. So, back to the question we started on "why console.log() returned undefined?"

console.log("Hello World");
//undefined

Go by the R-E-P-L rule, the console reads it and understands it to be a Javascript method. Now console* methods are designed to only output results to the console, there is no evaluation. It hence, logs "Hello World". And finally, from Example 5 we have learnt for functions that don't return value of evaluation, undefined is printed by default.

Final words...

Don't worry, if you felt like the guy in the GIF above, you are not alone. That was me too. Javascript is a wonderland, we all have got down the rabbit hole. More uncanny, peculiar, weirdly confusing concepts to face ahead. So, to get past them just try out code samples, explore, and break down as you did with me today to get to the bottom.