Visualizing a variety of statements for control, modules, and debugging.
An **Empty statement** (`;`) is a statement that does nothing. A **Block statement** (`{...}`) groups zero or more statements. It's often used with control flow statements like `if` and `for` to define a new scope for `let` and `const` variables.
if (condition) { // A block statement } else ; // An empty statement
A block statement creates a new scope. See the difference between `var` and `let` inside a block.
Outside Block:
let a = 1;
var b = 2;
Inside Block:
let a = 10;
(new `a`)
var b = 20;
(same `b`)
A **label** is an identifier followed by a colon (`:`). You can use it to identify a loop or a block, allowing `break` or `continue` to jump to a specific labeled block instead of just the immediate one.
outerLoop: for (let i = 0; i < 3; i++) { innerLoop: for (let j = 0; j < 3; j++) { if (j === 1) break outerLoop; // ... } }
Observe how a labeled `break` exits the outer loop.
The **`debugger`** statement invokes any available debugging functionality, such as setting a breakpoint. If no debugger is present, the statement has no effect.
function doSomething() { // code debugger; // Execution pauses here // more code }
Click the button and open your browser's Developer Tools (F12 or Cmd+Option+I) to see the effect.
The **`export`** and **`import`** statements are used to handle modules. `export` makes a variable, function, or class available to other files, while `import` brings them into the current file. These are essential for modern JavaScript development.
// In 'utils.js' export const PI = 3.14; // In 'main.js' import { PI } from './utils.js';
These statements cannot be run directly in this single-file HTML. However, they can be visualized as a transfer of data between files.
File `A` (`utils.js`)
export function add(a, b) { ... }
→
File `B` (`main.js`)
import { add } from './utils.js';
Data (`add` function) is now available in File B.
This statement is **deprecated**. Do not use it in new code.
The **`with`** statement was used to extend the scope chain for a block of code. This was a source of performance issues, security vulnerabilities, and code that was difficult to read and debug. It is strongly discouraged.
const user = { name: "John", city: "NYC" }; with (user) { // 'name' and 'city' are now in scope console.log(name); }
While the `with` statement might seem convenient, its side effects and performance pitfalls make it dangerous. It blurs the line between global and local scope, making it hard to determine where a variable is coming from.
A simple property access is clear:
console.log(user.name);
With `with`, it's ambiguous:
console.log(name);