What is the output of the given code and why?


var employeeId = 'abc123';

function foo() {
	employeeId = '123bcd';
	return;

	function employeeId() {}
}
foo();
console.log(employeeId);

What does the console say?

abc123. Can’t understand why though?

employeeId is a global variable because of not being declared with let or var

The function foo is called, and it stops when there is a return statement so the declaration of function employeeId is never executed, and employeeId stay a string

1 Like

Are you sure you are not getting a ReferenceError? In what environment did you run the code?

Running this through the debugger, as far as I can tell, this is what I get.

  1. In the creation faze the identifier employeeId is a function locally scoped to the foo function.

  2. Then in the execution faze the employeeId identifier get assigned the value “123bcd”, employeeId is not global because of the inner function declaration which setup the employeeId identifier locally (in the creation faze). It also doesn’t matter if the foo function returns after the assignment, the employeeId identifier will not be reassigned to the inner function in the execution faze (that setup is only part of the creation faze).

  3. When the code gets to the console.log() employeeId is still only available inside the foo function so you get a reference error.

I think that is right, or am I just crazy?

I think it depends if the environment has strict mode or not

I don’t think so.

The code below would work like that, in normal mode, it would make a global and error out in strict mode

function foo(){
  test = '123abc';
}
foo()
console.log(test) // 123abc
'use strict'
function foo(){
  test = '123abc';
}
foo()
console.log(test) // ReferenceError
1 Like

Sorry, the bad markdown hid the first line in the code, can you check again? For the older code there was reference error but this one seems to return abc123

Somehow I messed up the markdown, which hid the var employeeId = 'abc123' declaration, can you advise me about it now?

The only thing different about the new code is that the console.log() has access to the identifier/variable employeeId declared in the outer scope.

My point in 1 and 2 still stand and is why the outer employeeId is not overwritten. The inner function declaration acts as a variable declaration so the employeeId inside the foo function remains '123bcd' and is scoped to the function.

Without the inner function declaration, the assignment inside the foo function would overwrite the outer variable.

var employeeId = 'abc123';

function foo() {
	employeeId = '123bcd';
}
foo();
console.log(employeeId); // 123bcd

To avoid this from happening by accident using a function expression declared using let or const would help.

var employeeId = 'abc123';

function foo() {
	employeeId = '123bcd';
	return;

  // const employeeId = function() {}
  // or an arrow function
  const employeeId = () => {}
}
foo();
console.log(employeeId); // Uncaught ReferenceError: Cannot access 'employeeId' before initialization

On the other hand declaring the function expression using var might shed some light on why the original code works like it does, as it explicitly makes it clear the variable used by the assignment exists in the local scope.

var employeeId = 'abc123';

function foo() {
	employeeId = '123bcd';
	return;

  // const employeeId = function() {}
  // or an arrow function
  var employeeId = () => {}
}
foo();
console.log(employeeId); // abc123

Output will be abc123 from global variable employeeId and since foo() method return empty,so only output is abc123

It’s got nothing to do with what the function returns and everything to do with the inner function declaration acting as a local variable. Without the inner function declaration, the global variable will be overwritten by the assignment inside the foo function. As I already showed in my post above your post.

1 Like

why does this return reference error?

Technically the error is a TDZ error, but really the main take away is that because the function declaration is now using const you can’t reassign the value. You also can’t access it before initialization, which is the reference error we see in that example.

Here are the two different logs for each reference error.

TDZ error

console.log(test);
const test = "test"
// Uncaught ReferenceError: Cannot access 'test' before initialization

Assignment to const error

const test = "test"
test = 'no way dude'
// Uncaught TypeError: Assignment to constant variable.