Hone logo
Hone
Problems

Simulating JavaScript Hoisting in Jest Tests

JavaScript's hoisting behavior can be a source of confusion for developers. This challenge asks you to write Jest tests that demonstrate and verify this hoisting mechanism for both variable declarations and function declarations. Understanding hoisting is crucial for writing predictable and maintainable JavaScript code.

Problem Description

Your task is to create a suite of Jest tests in TypeScript that accurately simulate and assert the behavior of JavaScript hoisting. Specifically, you need to cover:

  1. Variable Hoisting (var): Test that var declared variables are accessible (though undefined) before their actual declaration in the code.
  2. Function Declaration Hoisting: Test that function declarations are fully hoisted and callable before their actual declaration.
  3. let and const Behavior (Temporal Dead Zone): While not strictly hoisting, it's essential to contrast var with let and const by testing that they are not accessible before their declaration, demonstrating the Temporal Dead Zone (TDZ).

Your tests should clearly show the expected values and potential errors (like ReferenceError) at different points in the execution flow.

Examples

Example 1: var Hoisting

// In your test file:
it('should demonstrate var hoisting', () => {
  expect(myVar).toBeUndefined(); // Accessing before declaration
  var myVar = 'Hello';
  expect(myVar).toBe('Hello');   // Accessing after declaration
});

Explanation: Before var myVar = 'Hello'; is executed, myVar is accessible due to hoisting but its value is undefined. After the declaration, it holds the assigned string.

Example 2: Function Declaration Hoisting

// In your test file:
it('should demonstrate function declaration hoisting', () => {
  greet(); // Calling before declaration
  function greet() {
    return 'Greetings!';
  }
  expect(greet()).toBe('Greetings!'); // Calling after declaration
});

Explanation: The greet function is hoisted and fully available for calling before its actual appearance in the code.

Example 3: let and const (Temporal Dead Zone)

// In your test file:
it('should demonstrate let and const are not hoisted before TDZ', () => {
  // expect(myLet).toBeUndefined(); // This would throw a ReferenceError
  // expect(myConst).toBeUndefined(); // This would also throw a ReferenceError

  let myLet = 'I am let';
  const myConst = 'I am const';

  expect(myLet).toBe('I am let');
  expect(myConst).toBe('I am const');
});

it('should throw ReferenceError when accessing let/const in TDZ', () => {
  expect(() => console.log(myLetTDZ)).toThrow(ReferenceError);
  // let myLetTDZ = 'TDZ example'; // Declaration would be here, but we are testing *before*
});

it('should throw ReferenceError when accessing const in TDZ', () => {
  expect(() => console.log(myConstTDZ)).toThrow(ReferenceError);
  // const myConstTDZ = 'TDZ example const'; // Declaration would be here
});

Explanation: Attempting to access myLetTDZ or myConstTDZ before their actual declarations results in a ReferenceError because they are in the Temporal Dead Zone. Unlike var, they are not initialized to undefined and hoisted.

Constraints

  • You must use Jest for testing.
  • Your tests must be written in TypeScript.
  • The tests should simulate common JavaScript hoisting scenarios.
  • Focus on demonstrating the behavior of hoisting and the TDZ through assertions, rather than reimplementing a JavaScript engine.

Notes

  • Consider how to structure your tests to isolate each hoisting concept (var, function declarations, let/const TDZ).
  • Think about how you would represent code that would execute before a declaration in a real JavaScript environment within the context of a Jest test.
  • Pay close attention to the type of error thrown for let and const within the TDZ.
Loading editor...
typescript