Mastering JavaScript Loops: Exploring the while and for Statements

Loops are essential tools in JavaScript (and programming in general) for executing a block of code repeatedly until a specified condition is met. The while and for loops are two fundamental loop structures that provide different ways to iterate through data or execute tasks. In this blog, we’ll delve into these loops, their syntax, use cases, and best practices.

The while Loop

The while loop repeatedly executes a block of code as long as a specified condition is true. Its syntax is straightforward:

while (condition) {
  // Code block to execute while condition is true
}

Let’s look at a simple example:

let count = 0;
while (count < 5) {
  console.log("Count: " + count);
  count++;
}

In this example:

  • The count variable is initialized to 0.
  • The while loop checks if count is less than 5.
  • If the condition is true, it executes the code block inside the loop (printing the current count) and increments count by 1.
  • This process continues until count is no longer less than 5.

The for Loop

The for loop is another commonly used loop that provides a more concise way to iterate through data. It consists of three optional expressions: initialization, condition, and final expression. Its syntax is as follows:

for (initialization; condition; final expression) {
  // Code block to execute
}

Let’s rewrite the previous example using a for loop:

for (let i = 0; i < 5; i++) {
  console.log("Count: " + i);
}

In this for loop:

  • let i = 0; initializes the loop counter i to 0.
  • i < 5; is the condition that checks if i is less than 5.
  • i++ is the final expression that increments i by 1 after each iteration.

Comparison: while vs. for

  • Use a while loop when you don’t know the exact number of iterations and are dependent on a condition to exit the loop.
  • Use a for loop when you know the exact number of iterations or when you need to control the initialization and final expression more explicitly.

Nested Loops

Loops can also be nested within each other to create more complex iterations. For example, a nested for loop to create a multiplication table:

for (let i = 1; i <= 5; i++) {
  for (let j = 1; j <= 5; j++) {
    console.log(i + " * " + j + " = " + i * j);
  }
}

Best Practices

  • Always ensure your loop has a clear exit condition to prevent infinite loops.
  • Use meaningful variable names (i, j, etc.) to improve readability.
  • Be cautious with nested loops, as they can impact performance, especially with large data sets.

Common Use Cases

  • Iterating Through Arrays:
  let colors = ["red", "green", "blue"];
  for (let i = 0; i < colors.length; i++) {
    console.log("Color: " + colors[i]);
  }
  • Summing Numbers:
  let sum = 0;
  for (let i = 1; i <= 10; i++) {
    sum += i;
  }
  console.log("Sum: " + sum); // Output: Sum: 55
  • Iterating Through Object Properties:
  let person = { name: "Alice", age: 30, city: "New York" };
  for (let key in person) {
    console.log(key + ": " + person[key]);
  }

Conclusion

Understanding while and for loops is crucial for writing efficient and concise JavaScript code. These loops provide the ability to iterate through data, execute tasks repeatedly, and control the flow of your programs.

As you continue your JavaScript journey, practice using while and for loops in various scenarios. Experiment with nested loops, loop control statements (break and continue), and different loop conditions to become comfortable with their usage.

By mastering loops, you gain the power to automate repetitive tasks, process data efficiently, and create dynamic applications that respond to changing conditions. So, the next time you need to iterate through an array, loop through object properties, or perform any repetitive task, reach for the while or for loop to handle the job with elegance and precision.

Functions

Mastering JavaScript Functions: The Building Blocks of Dynamic Code

Functions in JavaScript are powerful tools that allow you to encapsulate reusable blocks of code, making your programs more efficient, modular, and maintainable. Whether you’re a beginner or an experienced developer, understanding JavaScript functions is essential for writing clean and structured code. In this blog, we’ll explore the ins and outs of JavaScript functions, including their syntax, types, best practices, and common use cases.

What is a Function?

In programming, a function is a block of code that performs a specific task or calculates a value. It allows you to define a set of instructions that can be executed multiple times with different inputs. Functions help organize code into logical units, promote code reusability, and improve readability.

Declaring a Function

The syntax for declaring a function in JavaScript is straightforward:

function functionName(parameters) {
  // Code block to be executed
  return result; // Optional: Return a value
}

Let’s create a simple function that calculates the square of a number:

function square(number) {
  return number * number;
}

let result = square(5);
console.log("Square of 5:", result); // Output: Square of 5: 25

Function Parameters and Arguments

Functions can take parameters, which are placeholders for values passed into the function when it is called. These values are called arguments. Here’s an example:

function greet(name) {
  console.log("Hello, " + name + "!");
}

greet("Alice"); // Output: Hello, Alice!

Default Parameters

You can also set default parameter values for functions, which will be used if no argument is provided:

function greet(name = "Guest") {
  console.log("Hello, " + name + "!");
}

greet(); // Output: Hello, Guest!
greet("Bob"); // Output: Hello, Bob!

Return Statement

The return statement is used to specify the value that the function should return. A function can have multiple return statements, but only one will be executed:

function isEven(number) {
  if (number % 2 === 0) {
    return true;
  } else {
    return false;
  }
}

console.log(isEven(4)); // Output: true
console.log(isEven(7)); // Output: false

Function Expressions

In addition to the traditional function declaration, you can also create functions using function expressions. These are often used for functions that are not needed elsewhere in the code:

let multiply = function(x, y) {
  return x * y;
};

console.log(multiply(3, 4)); // Output: 12

Arrow Functions (ES6+)

Arrow functions provide a more concise syntax and lexical scoping of this. They are especially useful for one-liner functions:

let square = (number) => number * number;

console.log(square(6)); // Output: 36

Common Use Cases

  • Data Processing:
  function calculateTotal(price, quantity) {
    return price * quantity;
  }

  let total = calculateTotal(10, 3); // Output: 30
  • Event Handling:
  button.addEventListener("click", function() {
    alert("Button clicked!");
  });
  • Iterating Over Arrays:
  let numbers = [1, 2, 3, 4, 5];
  let squaredNumbers = numbers.map((num) => num * num);

Best Practices

  • Descriptive Names: Use meaningful names for functions to convey their purpose.
  • Single Responsibility: Each function should perform a single task for better maintainability.
  • Avoid Side Effects: Functions should ideally only modify local variables and return values rather than affecting external states.
  • Commenting: Add comments to explain the purpose of the function, parameters, and return values.

Conclusion

JavaScript functions are the building blocks of dynamic and modular code. By encapsulating logic into reusable units, functions make your code more organized, readable, and efficient. Whether you’re creating simple calculations, handling user interactions, or processing data, functions play a vital role in every JavaScript program.

As you continue your JavaScript journey, practice creating functions for various tasks. Experiment with different types of functions, such as arrow functions and function expressions, to gain a deeper understanding of their flexibility and usage. With a solid grasp of JavaScript functions, you’re equipped to tackle a wide range of programming challenges and build robust and scalable applications. So, embrace the power of functions, and let them guide you towards cleaner and more elegant code solutions.

The “switch” statement

Exploring the JavaScript switch Statement: A Comprehensive Guide

In JavaScript, the switch statement is a powerful tool for executing different blocks of code based on multiple possible conditions. This control flow statement provides an alternative to if-else chains when you have a series of conditions to evaluate. In this blog, we’ll dive into the switch statement, its syntax, use cases, and best practices.

The switch Statement Syntax

The switch statement evaluates an expression, matching its value to a case clause. If a match is found, the associated block of code is executed. If no match is found, an optional default case can be used to specify code to execute. Here’s the basic syntax:

switch (expression) {
  case value1:
    // Code block to execute if expression matches value1
    break;
  case value2:
    // Code block to execute if expression matches value2
    break;
  // Add more case statements as needed
  default:
    // Code block to execute if no case matches
}

Example: Using switch Statement

Let’s consider an example where we want to display a message based on the day of the week:

let dayOfWeek = 2;
let message;

switch (dayOfWeek) {
  case 1:
    message = "Today is Monday";
    break;
  case 2:
    message = "Today is Tuesday";
    break;
  case 3:
    message = "Today is Wednesday";
    break;
  case 4:
    message = "Today is Thursday";
    break;
  case 5:
    message = "Today is Friday";
    break;
  case 6:
    message = "Today is Saturday";
    break;
  case 7:
    message = "Today is Sunday";
    break;
  default:
    message = "Invalid day of the week";
}

console.log(message); // Output: "Today is Tuesday"

In this example:

  • The dayOfWeek variable is set to 2, representing Tuesday.
  • The switch statement evaluates dayOfWeek against each case.
  • When case 2 is matched, the corresponding message is assigned to message.
  • The break statement is crucial as it exits the switch block once a case is matched. Without it, execution would continue into subsequent cases.

Using switch with String Values

The switch statement can also be used with string values in JavaScript, which is a feature not available in some other programming languages. Here’s an example:

let fruit = "apple";
let message;

switch (fruit) {
  case "apple":
    message = "You chose an apple";
    break;
  case "banana":
    message = "You chose a banana";
    break;
  case "orange":
    message = "You chose an orange";
    break;
  default:
    message = "Unknown fruit";
}

console.log(message); // Output: "You chose an apple"

Common Use Cases

  • Menu Selection: Responding to different menu selections in a web application.
  • State Management: Handling different states in a game or application.
  • Error Handling: Providing specific error messages based on different error codes.

Best Practices

  • Use break Statements: Always include break statements to prevent “fall-through” behavior.
  • Default Case: Include a default case for handling unexpected or unhandled values.
  • Avoid Complex Conditions: switch statements work best with simple equality comparisons, not complex conditions.

Nested switch Statements

Just like if statements, switch statements can be nested within each other for more complex scenarios. However, nesting should be done cautiously to maintain readability.

Conclusion

The switch statement in JavaScript provides a concise and structured way to handle multiple conditions. Whether you’re working with numerical values, strings, or even other types, switch offers a clean and efficient alternative to lengthy if-else chains.

As you become more comfortable with JavaScript, incorporating switch statements into your code can lead to clearer, more organized logic. Remember to use break statements to avoid unintended fall-through and always include a default case for handling unexpected values.

So, the next time you find yourself in a situation where you need to execute different blocks of code based on various conditions, reach for the switch statement. With its flexibility and readability, it’s a valuable tool in your JavaScript programming arsenal.

Logical operators

Unraveling JavaScript Logical Operators: A Comprehensive Guide

In the world of JavaScript programming, logical operators are the building blocks of decision-making and complex conditions. They allow developers to create logical expressions that evaluate to true or false, enabling dynamic control flow in their code. In this blog, we’ll explore the logical operators in JavaScript, including && (AND), || (OR), and ! (NOT), along with their practical applications and best practices.

1. AND Operator (&&)

The AND (&&) operator returns true if both operands are true; otherwise, it returns false. It is often used to combine multiple conditions.

// Example of the AND operator
let isAdult = true;
let hasLicense = true;

if (isAdult && hasLicense) {
  console.log("You can drive!");
} else {
  console.log("You are not eligible to drive.");
}

In this example, the message “You can drive!” will be printed only if both isAdult and hasLicense are true.

2. OR Operator (||)

The OR (||) operator returns true if at least one of the operands is true. It is used to create conditions where either of the conditions can be true.

// Example of the OR operator
let isWeekend = false;
let isHoliday = true;

if (isWeekend || isHoliday) {
  console.log("It's time to relax!");
} else {
  console.log("Back to work!");
}

Here, the message “It’s time to relax!” will be printed if either isWeekend or isHoliday is true.

3. NOT Operator (!)

The NOT (!) operator is a unary operator that reverses the logical state of its operand. If the operand is true, ! makes it false, and vice versa.

// Example of the NOT operator
let isLoggedOut = true;

if (!isLoggedOut) {
  console.log("Welcome back!");
} else {
  console.log("Please log in.");
}

In this case, the message “Please log in.” will be printed because !isLoggedOut evaluates to false.

Combining Logical Operators

Logical operators can be combined to create more complex conditions. They have precedence rules (! has the highest precedence, followed by &&, then ||), but parentheses can be used to clarify the order of operations.

// Combining logical operators
let isStudent = true;
let isRegistered = false;
let isEnrolled = true;

if (isStudent && (isRegistered || isEnrolled)) {
  console.log("You are ready for the course.");
} else {
  console.log("Please complete your registration.");
}

In this example, the message “You are ready for the course.” will be printed if isStudent is true and either isRegistered or isEnrolled is true.

Practical Applications

  • Form Validation: Checking if all required fields are filled (&&) or allowing different validation scenarios (||).
  • User Permissions: Determining if a user has the necessary permissions (&&) or providing access in specific situations (||).
  • Conditional Rendering: Showing different content based on various conditions in a user interface.

Best Practices

  • Use Parentheses for Clarity: When combining multiple logical operators, use parentheses to ensure the intended order of operations.
  • Avoid Overly Complex Conditions: Complex conditions can lead to confusion. Break them down into smaller, more manageable parts if needed.
  • Understand Short-circuiting: JavaScript’s logical operators have short-circuiting behavior, where the evaluation stops as soon as the result is known.

Conclusion

Logical operators in JavaScript provide powerful tools for creating dynamic and flexible conditions in your code. Whether you need to check multiple conditions, handle different scenarios, or validate user input, && (AND), || (OR), and ! (NOT) operators are indispensable.

By mastering these operators, you gain the ability to create robust and efficient JavaScript applications. So, the next time you’re faced with complex decision-making in your code, reach for these logical operators to craft elegant and effective solutions. With logical operators, you have the power to navigate through various scenarios and create intelligent, responsive applications that meet your users’ needs.

Loops: while and for

We often need to repeat actions.

For example, outputting goods from a list one after another or just running the same code for each number from 1 to 10.

Loops are a way to repeat the same code multiple times.

The “while” loop

The while loop has the following syntax:

while (condition) {
  // code
  // so-called "loop body"
}

While the condition is truthy, the code from the loop body is executed.

For instance, the loop below outputs i while i < 3:

let i = 0;
while (i < 3) { // shows 0, then 1, then 2
  alert( i );
  i++;
}

A single execution of the loop body is called an iteration. The loop in the example above makes three iterations.

If i++ was missing from the example above, the loop would repeat (in theory) forever. In practice, the browser provides ways to stop such loops, and in server-side JavaScript, we can kill the process.

Any expression or variable can be a loop condition, not just comparisons: the condition is evaluated and converted to a boolean by while.

For instance, a shorter way to write while (i != 0) is while (i):

let i = 3;
while (i) { // when i becomes 0, the condition becomes falsy, and the loop stops
  alert( i );
  i--;
}

Curly braces are not required for a single-line body

If the loop body has a single statement, we can omit the curly braces {…}:

let i = 3;
while (i) alert(i--);

The “do…while” loop

The condition check can be moved below the loop body using the do..while syntax:

do {
  // loop body
} while (condition);

The loop will first execute the body, then check the condition, and, while it’s truthy, execute it again and again.

For example:

let i = 0;
do {
  alert( i );
  i++;
} while (i < 3);

This form of syntax should only be used when you want the body of the loop to execute at least once regardless of the condition being truthy. Usually, the other form is preferred: while(…) {…}.

The “for” loop

The for loop is more complex, but it’s also the most commonly used loop.

It looks like this:

for (begin; condition; step) {
  // ... loop body ...
}

Let’s learn the meaning of these parts by example. The loop below runs alert(i) for i from 0 up to (but not including) 3:

for (let i = 0; i < 3; i++) { // shows 0, then 1, then 2
  alert(i);
}

Let’s examine the for statement part-by-part:

part
begini = 0Executes once upon entering the loop.
conditioni < 3Checked before every loop iteration. If false, the loop stops.
bodyalert(i)Runs again and again while the condition is truthy.
stepi++Executes after the body on each iteration.

The general loop algorithm works like this:

Run begin
→ (if condition → run body and run step)
→ (if condition → run body and run step)
→ (if condition → run body and run step)
→ ...

That is, begin executes once, and then it iterates: after each condition test, body and step are executed.

If you are new to loops, it could help to go back to the example and reproduce how it runs step-by-step on a piece of paper.

Here’s exactly what happens in our case:

// for (let i = 0; i < 3; i++) alert(i)

// run begin
let i = 0
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// if condition → run body and run step
if (i < 3) { alert(i); i++ }
// ...finish, because now i == 3

Inline variable declaration

Here, the “counter” variable i is declared right in the loop. This is called an “inline” variable declaration. Such variables are visible only inside the loop.

for (let i = 0; i < 3; i++) {
  alert(i); // 0, 1, 2
}
alert(i); // error, no such variable

Instead of defining a variable, we could use an existing one:

let i = 0;

for (i = 0; i < 3; i++) { // use an existing variable
  alert(i); // 0, 1, 2
}

alert(i); // 3, visible, because declared outside of the loop

Skipping parts

Any part of for can be skipped.

For example, we can omit begin if we don’t need to do anything at the loop start.

Like here:

let i = 0; // we have i already declared and assigned

for (; i < 3; i++) { // no need for "begin"
  alert( i ); // 0, 1, 2
}

We can also remove the step part:

let i = 0;

for (; i < 3;) {
  alert( i++ );
}

This makes the loop identical to while (i < 3).

We can actually remove everything, creating an infinite loop:

for (;;) {
  // repeats without limits
}

Please note that the two for semicolons ; must be present. Otherwise, there would be a syntax error.

Breaking the loop

Normally, a loop exits when its condition becomes falsy.

But we can force the exit at any time using the special break directive.

For example, the loop below asks the user for a series of numbers, “breaking” when no number is entered:

let sum = 0;

while (true) {

  let value = +prompt("Enter a number", '');

  if (!value) break; // (*)

  sum += value;

}
alert( 'Sum: ' + sum );

The break directive is activated at the line (*) if the user enters an empty line or cancels the input. It stops the loop immediately, passing control to the first line after the loop. Namely, alert.

The combination “infinite loop + break as needed” is great for situations when a loop’s condition must be checked not in the beginning or end of the loop, but in the middle or even in several places of its body.

Continue to the next iteration

The continue directive is a “lighter version” of break. It doesn’t stop the whole loop. Instead, it stops the current iteration and forces the loop to start a new one (if the condition allows).

We can use it if we’re done with the current iteration and would like to move on to the next one.

The loop below uses continue to output only odd values:

for (let i = 0; i < 10; i++) {

  // if true, skip the remaining part of the body
  if (i % 2 == 0) continue;

  alert(i); // 1, then 3, 5, 7, 9
}

For even values of i, the continue directive stops executing the body and passes control to the next iteration of for (with the next number). So the alert is only called for odd values.The continue directive helps decrease nesting

A loop that shows odd values could look like this:

for (let i = 0; i < 10; i++) {

  if (i % 2) {
    alert( i );
  }

}

From a technical point of view, this is identical to the example above. Surely, we can just wrap the code in an if block instead of using continue.

But as a side-effect, this created one more level of nesting (the alert call inside the curly braces). If the code inside of if is longer than a few lines, that may decrease the overall readability.No break/continue to the right side of ‘?’

Please note that syntax constructs that are not expressions cannot be used with the ternary operator ?. In particular, directives such as break/continue aren’t allowed there.

For example, if we take this code:

if (i > 5) {
  alert(i);
} else {
  continue;
}

…and rewrite it using a question mark:

(i > 5) ? alert(i) : continue; // continue isn't allowed here

…it stops working: there’s a syntax error.

This is just another reason not to use the question mark operator ? instead of if.

Labels for break/continue

Sometimes we need to break out from multiple nested loops at once.

For example, in the code below we loop over i and j, prompting for the coordinates (i, j) from (0,0) to (2,2):

for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`Value at coords (${i},${j})`, '');

    // what if we want to exit from here to Done (below)?
  }
}

alert('Done!');

We need a way to stop the process if the user cancels the input.

The ordinary break after input would only break the inner loop. That’s not sufficient – labels, come to the rescue!

label is an identifier with a colon before a loop:

labelName: for (...) {
  ...
}

The break <labelName> statement in the loop below breaks out to the label:

outer: for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`Value at coords (${i},${j})`, '');

    // if an empty string or canceled, then break out of both loops
    if (!input) break outer; // (*)

    // do something with the value...
  }
}
alert('Done!');

In the code above, break outer looks upwards for the label named outer and breaks out of that loop.

So the control goes straight from (*) to alert('Done!').

We can also move the label onto a separate line:

outer:
for (let i = 0; i < 3; i++) { ... }

The continue directive can also be used with a label. In this case, code execution jumps to the next iteration of the labeled loop.Labels do not allow to “jump” anywhere

Labels do not allow us to jump into an arbitrary place in the code.

For example, it is impossible to do this:

break label; // jump to the label below (doesn't work)

label: for (...)

break directive must be inside a code block. Technically, any labelled code block will do, e.g.:

label: {
  // ...
  break label; // works
  // ...
}

…Although, 99.9% of the time break used is inside loops, as we’ve seen in the examples above.

continue is only possible from inside a loop.

Summary

We covered 3 types of loops:

  • while – The condition is checked before each iteration.
  • do..while – The condition is checked after each iteration.
  • for (;;) – The condition is checked before each iteration, additional settings available.

To make an “infinite” loop, usually the while(true) construct is used. Such a loop, just like any other, can be stopped with the break directive.

If we don’t want to do anything in the current iteration and would like to forward to the next one, we can use the continue directive.

break/continue support labels before the loop. A label is the only way for break/continue to escape a nested loop to go to an outer one.

Tasks

Last loop value

importance: 3

What is the last value alerted by this code? Why?

let i = 3;

while (i) {
  alert( i-- );
}

solution

Which values does the while loop show?

importance: 4

For every loop iteration, write down which value it outputs and then compare it with the solution.

Both loops alert the same values, or not?

  1. The prefix form ++i:let i = 0; while (++i < 5) alert( i );
  2. The postfix form i++let i = 0; while (i++ < 5) alert( i );

solution

Which values get shown by the “for” loop?

importance: 4

For each loop write down which values it is going to show. Then compare with the answer.

Both loops alert same values or not?

  1. The postfix form:for (let i = 0; i < 5; i++) alert( i );
  2. The prefix form:for (let i = 0; i < 5; ++i) alert( i );

solution

Output even numbers in the loop

importance: 5

Use the for loop to output even numbers from 2 to 10.

Run the demosolution

Replace “for” with “while”

importance: 5

Rewrite the code changing the for loop to while without altering its behavior (the output should stay same).

for (let i = 0; i < 3; i++) {
  alert( `number ${i}!` );
}

solution

Repeat until the input is correct

importance: 5

Write a loop which prompts for a number greater than 100. If the visitor enters another number – ask them to input again.

The loop must ask for a number until either the visitor enters a number greater than 100 or cancels the input/enters an empty line.

Here we can assume that the visitor only inputs numbers. There’s no need to implement a special handling for a non-numeric input in this task.

Run the demosolution

Output prime numbers

importance: 3

An integer number greater than 1 is called a prime if it cannot be divided without a remainder by anything except 1 and itself.

In other words, n > 1 is a prime if it can’t be evenly divided by anything except 1 and n.

For example, 5 is a prime, because it cannot be divided without a remainder by 23 and 4.

Write the code which outputs prime numbers in the interval from 2 to n.

For n = 10 the result will be 2,3,5,7.

P.S. The code should work for any n, not be hard-tuned for any fixed value.

Conditional branching: if, ‘?’

Mastering Conditional Branching in JavaScript: The if Statement and Ternary Operator

Conditional branching is a fundamental concept in programming, allowing developers to create dynamic behavior based on conditions. In JavaScript, two primary tools for conditional branching are the if statement and the ternary operator (? :). In this blog, we’ll explore these constructs, their syntax, and common use cases.

The if Statement

The if statement is a foundational building block of JavaScript programming. It allows you to execute a block of code if a specified condition is true. Here’s the basic syntax:

if (condition) {
  // Code block to execute if condition is true
} else {
  // Code block to execute if condition is false
}

Let’s look at a simple example:

let temperature = 25;

if (temperature > 30) {
  console.log("It's a hot day!");
} else if (temperature > 20) {
  console.log("It's a nice day.");
} else {
  console.log("It's a cold day.");
}

In this example:

  • If temperature is greater than 30, “It’s a hot day!” will be printed.
  • If temperature is greater than 20 but not greater than 30, “It’s a nice day.” will be printed.
  • If temperature is 20 or lower, “It’s a cold day.” will be printed.

The Ternary Operator (? :)

The ternary operator provides a concise way to write simple if-else statements in a single line. It’s often used for assigning values based on a condition. The syntax is as follows:

condition ? expression1 : expression2

If condition is true, expression1 is evaluated; otherwise, expression2 is evaluated. Here’s an example:

let age = 20;
let message = (age >= 18) ? "You are an adult" : "You are not an adult";

console.log(message); // Output: "You are an adult"

Nested if Statements

You can also nest if statements within each other to handle more complex conditions. Here’s an example:

let score = 85;
let grade;

if (score >= 90) {
  grade = "A";
} else {
  if (score >= 80) {
    grade = "B";
  } else {
    grade = "C";
  }
}

console.log("Your grade is: " + grade); // Output: "Your grade is: B"

Common Use Cases

  • User Authentication:
  let isLoggedIn = true;
  let message = isLoggedIn ? "Welcome back!" : "Please log in.";
  • Validation:
  let input = "123";
  let isValid = (input.length > 0) ? true : false;
  • Conditional Rendering in UI:
  let isAdmin = false;
  let adminPanel = isAdmin ? "<AdminPanel />" : "<UserPanel />";

Best Practices

  • Use clear and descriptive conditions for readability.
  • Properly indent nested if statements for better code organization.
  • Consider readability and simplicity when deciding between the if statement and the ternary operator.

Conclusion

Conditional branching is a powerful feature of JavaScript that allows you to control the flow of your code based on different conditions. The if statement provides a traditional and versatile way to handle conditions, while the ternary operator offers a concise alternative for simple if-else scenarios.

By mastering these tools, you can create dynamic and responsive applications that adapt to various scenarios. Whether you’re building a user interface that responds to user input or implementing logic for data processing, conditional branching is a vital skill for any JavaScript developer.

So, the next time you need to make decisions in your code, reach for the if statement or the ternary operator to handle those conditions effectively. With these tools in your programming toolbox, you have the power to create sophisticated and intelligent JavaScript applications.

Interaction: alert, prompt, confirm

JavaScript Interaction: Exploring alert(), prompt(), and confirm()

JavaScript, the language that breathes life into web pages, offers powerful ways to interact with users through alert boxes, prompts for input, and confirmation dialogs. These simple yet effective tools are essential for creating dynamic and engaging user experiences. In this blog, we’ll delve into JavaScript’s alert(), prompt(), and confirm() functions, exploring how they enhance interactivity on the web.

1. Alert Boxes with alert()

The alert() function is used to display a message box with a specified message and an OK button. It’s commonly used for displaying information to users or notifying them of important updates.

alert("Welcome to our website!");

2. Prompting for Input with prompt()

The prompt() function displays a dialog box that prompts the user for input. It takes two arguments: the message to display and an optional default value.

let userName = prompt("Please enter your name:", "John Doe");

if (userName !== null) {
  alert("Hello, " + userName + "! Welcome to our site.");
} else {
  alert("You did not enter a name. Please refresh and try again.");
}

In this example, the user is prompted to enter their name. If they click “OK” without entering anything or click “Cancel,” the prompt() function returns null.

3. Confirmation Dialogs with confirm()

The confirm() function displays a dialog box with a message and two buttons: OK and Cancel. It’s commonly used for obtaining user consent or confirmation for an action.

let userChoice = confirm("Are you sure you want to delete this item?");

if (userChoice) {
  // Delete the item
  alert("Item deleted successfully.");
} else {
  alert("Operation canceled.");
}

When the user clicks “OK,” confirm() returns true. If the user clicks “Cancel,” it returns false.

Best Practices and Use Cases

  • Error Handling: Use alert() to notify users of errors or incorrect inputs.
  • User Input: Use prompt() to gather user input for forms or customization options.
  • Confirmation: Use confirm() to confirm critical actions such as deleting items or submitting forms.

Enhancing User Experience

These interaction functions are essential for creating user-friendly interfaces. However, it’s important to use them judiciously to avoid disrupting the user experience with excessive alerts or prompts.

Handling User Input

When using prompt(), always validate and sanitize user input to prevent security vulnerabilities and ensure data integrity. Here’s an example of validating user input for a number:

let userInput = prompt("Please enter a number:");

if (userInput !== null) {
  let number = parseInt(userInput);

  if (!isNaN(number)) {
    alert("You entered: " + number);
  } else {
    alert("Invalid input. Please enter a valid number.");
  }
} else {
  alert("You canceled the operation.");
}

Conclusion

JavaScript’s alert(), prompt(), and confirm() functions are indispensable tools for creating interactive and user-friendly web applications. Whether you’re welcoming users, gathering input, or confirming actions, these functions provide a seamless way to engage with your audience.

As you integrate these functions into your projects, remember to:

  • Use them sparingly to avoid overwhelming users.
  • Validate and sanitize user input for security and data integrity.
  • Provide clear and concise messages to guide users through interactions.

By harnessing the power of JavaScript’s interaction functions, you can create web experiences that are not only informative but also intuitive and engaging. So, next time you need to communicate with your users, reach for alert(), prompt(), and confirm() to add that extra layer of interactivity to your web applications.

Developer console

Code is always prone to errors. You will quite often likely make errors… Oh, what we are discussing ? You are absolutely going to make errors, at least if you’re a human, not a robot.

But in the browser, users don’t see errors by default in the webpage. So, if something goes broken or wrong in the script, we won’t see what’s broken and can’t fix it.

To see errors and get a lot of other useful information about scripts, “developer tools” the best place where we can c how our code have been embedded in browsers.

Most developers lean towards Chrome or Firefox for development because those browsers have the best developer tools. You can open your developer tool by the combination of keypress (Ctrl+Shift+I) . Other browsers also provide developer tools, sometimes with special features, but are usually playing “catch-up” to Chrome or Firefox. So most developers have a “favorite” browser and switch to others if a problem is browser-specific.

Developer tools are potent; they have many features. To start, we’ll learn how to open them, look at errors, and run JavaScript commands.

Google Chrome(Ctrl+Shift+I)

Open the page bug.html.

There’s an error in the JavaScript code on it. It’s hidden from a regular visitor’s eyes, so let’s open developer tools to see it.

Alternative method Press F12 or, if you’re on Mac, then Cmd+Opt+J.

The developer tools will open on the Console tab by default.

It looks somewhat like this:

The exact look of developer tools depends on your version of Chrome. It changes from time to time but should be similar.

  • Here we can see the red-colored error message. In this case, the script contains an unknown “lalala” command.
  • On the right, there is a clickable link to the source bug.html:12 with the line number where the error has occurred.

Below the error message, there is a blue > symbol. It marks a “command line” where we can type JavaScript commands. Press Enter to run them (Shift+Enter to input multi-line commands).

Now we can see errors, and that’s enough for a start. We’ll come back to developer tools later and cover debugging more in-depth in the chapter Debugging in Chrome.

Firefox, Edge, and others

Most other browsers use F12 to open developer tools.

The look & feel of them is quite similar. Once you know how to use one of these tools (you can start with Chrome), you can easily switch to another.

Safari

Safari (Mac browser, not supported by Windows/Linux) is a little bit special here. We need to enable the “Develop menu” first.

Open Preferences and go to the “Advanced” pane. There’s a checkbox at the bottom:

Now Cmd+Opt+C can toggle the console. Also, note that the new top menu item named “Develop” has appeared. It has many commands and options.

Summary

  • Developer tools allow us to see errors, run commands, examine variables, and much more.
  • They can be opened with F12 for most browsers on Windows. Chrome for Mac needs Cmd+Opt+J, Safari: Cmd+Opt+C(need to enable first).

Now we have the environment ready. In the next section, we’ll get down to JavaScript.

Java Script | Comparisons

We know many comparison operators from maths.

In JavaScript they are written like this:

  • Greater/less than: a > ba < b.
  • Greater/less than or equals: a >= ba <= b.
  • Equals: a == b, please note the double equality sign == means the equality test, while a single one a = b means an assignment.
  • Not equals. In maths the notation is , but in JavaScript it’s written as a != b.

In this article we’ll learn more about different types of comparisons, how JavaScript makes them, including important peculiarities.

At the end you’ll find a good recipe to avoid “JavaScript quirks”-related issues.

Boolean is the result

All comparison operators return a boolean value:

  • true – means “yes”, “correct” or “the truth”.
  • false – means “no”, “wrong” or “not the truth”.

For example:

alert( 2 > 1 );  // true (correct)
alert( 2 == 1 ); // false (wrong)
alert( 2 != 1 ); // true (correct)

A comparison result can be assigned to a variable, just like any value:

let result = 5 > 4; // assign the result of the comparison
alert( result ); // true

String comparison

To see whether a string is greater than another, JavaScript uses the so-called “dictionary” or “lexicographical” order.

In other words, strings are compared letter-by-letter.

For example:

alert( 'Z' > 'A' ); // true
alert( 'Glow' > 'Glee' ); // true
alert( 'Bee' > 'Be' ); // true

The algorithm to compare two strings is simple:

  1. Compare the first character of both strings.
  2. If the first character from the first string is greater (or less) than the other string’s, then the first string is greater (or less) than the second. We’re done.
  3. Otherwise, if both strings’ first characters are the same, compare the second characters the same way.
  4. Repeat until the end of either string.
  5. If both strings end at the same length, then they are equal. Otherwise, the longer string is greater.

In the first example above, the comparison 'Z' > 'A' gets to a result at the first step.

The second comparison 'Glow' and 'Glee' needs more steps as strings are compared character-by-character:

  1. G is the same as G.
  2. l is the same as l.
  3. o is greater than e. Stop here. The first string is greater.

Not a real dictionary, but Unicode order

The comparison algorithm given above is roughly equivalent to the one used in dictionaries or phone books, but it’s not exactly the same.

For instance, case matters. A capital letter "A" is not equal to the lowercase "a". Which one is greater? The lowercase "a". Why? Because the lowercase character has a greater index in the internal encoding table JavaScript uses (Unicode). We’ll get back to specific details and consequences of this in the chapter Strings.

Comparison of different types

When comparing values of different types, JavaScript converts the values to numbers.

For example:

alert( '2' > 1 ); // true, string '2' becomes a number 2
alert( '01' == 1 ); // true, string '01' becomes a number 1

For boolean values, true becomes 1 and false becomes 0.

For example:

alert( true == 1 ); // true
alert( false == 0 ); // true

A funny consequence

It is possible that at the same time:

  • Two values are equal.
  • One of them is true as a boolean and the other one is false as a boolean.

For example:

let a = 0;
alert( Boolean(a) ); // false

let b = "0";
alert( Boolean(b) ); // true

alert(a == b); // true!

From JavaScript’s standpoint, this result is quite normal. An equality check converts values using the numeric conversion (hence "0" becomes 0), while the explicit Boolean conversion uses another set of rules.

Strict equality

A regular equality check == has a problem. It cannot differentiate 0 from false:

alert( 0 == false ); // true

The same thing happens with an empty string:

alert( '' == false ); // true

This happens because operands of different types are converted to numbers by the equality operator ==. An empty string, just like false, becomes a zero.

What to do if we’d like to differentiate 0 from false?

A strict equality operator === checks the equality without type conversion.

In other words, if a and b are of different types, then a === b immediately returns false without an attempt to convert them.

Let’s try it:

alert( 0 === false ); // false, because the types are different

There is also a “strict non-equality” operator !== analogous to !=.

The strict equality operator is a bit longer to write, but makes it obvious what’s going on and leaves less room for errors.

Comparison with null and undefined

There’s a non-intuitive behavior when null or undefined are compared to other values.For a strict equality check ===

These values are different, because each of them is a different type.

alert( null === undefined ); // false

For a non-strict check ==

There’s a special rule. These two are a “sweet couple”: they equal each other (in the sense of ==), but not any other value.

alert( null == undefined ); // true

For maths and other comparisons < > <= >=

null/undefined are converted to numbers: null becomes 0, while undefined becomes NaN.

Now let’s see some funny things that happen when we apply these rules. And, what’s more important, how to not fall into a trap with them.

Strange result: null vs 0

Let’s compare null with a zero:

alert( null > 0 );  // (1) false
alert( null == 0 ); // (2) false
alert( null >= 0 ); // (3) true

Mathematically, that’s strange. The last result states that “null is greater than or equal to zero”, so in one of the comparisons above it must be true, but they are both false.

The reason is that an equality check == and comparisons > < >= <= work differently. Comparisons convert null to a number, treating it as 0. That’s why (3) null >= 0 is true and (1) null > 0 is false.

On the other hand, the equality check == for undefined and null is defined such that, without any conversions, they equal each other and don’t equal anything else. That’s why (2) null == 0 is false.

An incomparable undefined

The value undefined shouldn’t be compared to other values:

alert( undefined > 0 ); // false (1)
alert( undefined < 0 ); // false (2)
alert( undefined == 0 ); // false (3)

Why does it dislike zero so much? Always false!

We get these results because:

  • Comparisons (1) and (2) return false because undefined gets converted to NaN and NaN is a special numeric value which returns false for all comparisons.
  • The equality check (3) returns false because undefined only equals nullundefined, and no other value.

Avoid problems

Why did we go over these examples? Should we remember these peculiarities all the time? Well, not really. Actually, these tricky things will gradually become familiar over time, but there’s a solid way to avoid problems with them:

  • Treat any comparison with undefined/null except the strict equality === with exceptional care.
  • Don’t use comparisons >= > < <= with a variable which may be null/undefined, unless you’re really sure of what you’re doing. If a variable can have these values, check for them separately.

Summary

  • Comparison operators return a boolean value.
  • Strings are compared letter-by-letter in the “dictionary” order.
  • When values of different types are compared, they get converted to numbers (with the exclusion of a strict equality check).
  • The values null and undefined equal == each other and do not equal any other value.
  • Be careful when using comparisons like > or < with variables that can occasionally be null/undefined. Checking for null/undefined separately is a good idea.

Tasks

Comparisons

importance: 5

What will be the result for these expressions?

5 > 4
"apple" > "pineapple"
"2" > "12"
undefined == null
undefined === null
null == "\n0\n"
null === +"\n0\n"

solution

The modern mode, “use strict”

For a long time, JavaScript evolved without compatibility issues. New features were added to the language while old functionality didn’t change.

That had the benefit of never breaking existing code. But the downside was that any mistake or an imperfect decision made by JavaScript’s creators got stuck in the language forever.

This was the case until 2009 when ECMAScript 5 (ES5) appeared. It added new features to the language and modified some of the existing ones. To keep the old code working, most such modifications are off by default. You need to explicitly enable them with a special directive: "use strict".

“use strict”

The directive looks like a string: "use strict" or 'use strict'. When it is located at the top of a script, the whole script works the “modern” way.

For example:

"use strict";

// this code works the modern way
...

Quite soon we’re going to learn functions (a way to group commands), so let’s note in advance that "use strict" can be put at the beginning of a function. Doing that enables strict mode in that function only. But usually people use it for the whole script.Ensure that “use strict” is at the top

Please make sure that "use strict" is at the top of your scripts, otherwise strict mode may not be enabled.

Strict mode isn’t enabled here:

alert("some code");
// "use strict" below is ignored--it must be at the top

"use strict";

// strict mode is not activated

Only comments may appear above "use strict".There’s no way to cancel use strict

There is no directive like "no use strict" that reverts the engine to old behavior.

Once we enter strict mode, there’s no going back.

Browser console

When you use a developer console to run code, please note that it doesn’t use strict by default.

Sometimes, when use strict makes a difference, you’ll get incorrect results.

So, how to actually use strict in the console?

First, you can try to press Shift+Enter to input multiple lines, and put use strict on top, like this:

'use strict'; <Shift+Enter for a newline>
//  ...your code
<Enter to run>

It works in most browsers, namely Firefox and Chrome.

If it doesn’t, e.g. in an old browser, there’s an ugly, but reliable way to ensure use strict. Put it inside this kind of wrapper:

(function() {
  'use strict';

  // ...your code here...
})()

Should we “use strict”?

The question may sound obvious, but it’s not so.

One could recommend to start scripts with "use strict"… But you know what’s cool?

Modern JavaScript supports “classes” and “modules” – advanced language structures (we’ll surely get to them), that enable use strict automatically. So we don’t need to add the "use strict" directive, if we use them.

So, for now "use strict"; is a welcome guest at the top of your scripts. Later, when your code is all in classes and modules, you may omit it.

As of now, we’ve got to know about use strict in general.

In the next chapters, as we learn language features, we’ll see the differences between the strict and old modes. Luckily, there aren’t many and they actually make our lives better.

All examples in this tutorial assume strict mode unless (very rarely) specified otherwise.