Javascript
  • intro.
  • 1 - Getting started
  • 2 - Basics
  • 3 - Functions and Scope
  • 4 - Advanced Concepts
  • 5 - JavaScript in the Browser
  • 6 - JavaScript and Browser Storage
  • 7 - Asynchronous JavaScript
  • 8 - Design Patterns
  • 9 - Frameworks Overview
  • 10 - Testing and Debugging
Powered by GitBook
On this page
  • Functions in JavaScript
  • What is a Function?
  • Declaring Functions
  • Parameters and Arguments
  • Return Values
  • Scope in JavaScript
  • Types of Scope
  • Block Scope
  • Lexical Scope and Closures
  • Arrow Functions vs Regular Functions

3 - Functions and Scope

Functions in JavaScript

What is a Function?

  • Function: A reusable block of code that performs a specific task.

  • Benefits: Reusability, modularity, easier testing, and maintenance.

  • Anatomy of a Function: Consists of a function name, parameters (optional), a function body, and a return value (optional).

    • Syntax:

      function functionName(parameters) {
          // function body
          return value;  // optional
      }

Declaring Functions

  • Function Declaration:

    • Example:

      function greet() {
          console.log("Hello, World!");
      }
      greet();  // Output: "Hello, World!"
    • Hoisting: Function declarations are hoisted, meaning they can be called before they are defined in the code.

      greet();  // Output: "Hello again!"
      function greet() {
          console.log("Hello again!");
      }
  • Function Expression: A function assigned to a variable.

    • Example:

      const sayHello = function() {
          console.log("Hello from Function Expression!");
      };
      sayHello();  // Output: "Hello from Function Expression!"
    • Hoisting: Function expressions are not hoisted, which means they cannot be called before they are defined.

      // sayHello();  // Error: Cannot access 'sayHello' before initialization
      const sayHello = function() {
          console.log("Hello!");
      };
  • Arrow Functions: A concise way to write functions (introduced in ES6).

    • Syntax Examples:

      const add = (a, b) => a + b;
      console.log(add(3, 4));  // Output: 7
      
      const greet = () => console.log("Hello, Arrow Function!");
      greet();  // Output: "Hello, Arrow Function!"
    • When to Use: Arrow functions are ideal for callbacks and one-liners, but they do not have their own this.

Parameters and Arguments

  • Parameters: Placeholders for values the function can receive.

  • Arguments: Actual values passed to the function.

    • Example:

      function greetUser(name) {
          console.log("Hello, " + name + "!");
      }
      greetUser("Alice");  // Output: "Hello, Alice!"
  • Default Parameters: Providing default values to parameters.

    • Example:

      function greetUser(name = "Guest") {
          console.log("Hello, " + name + "!");
      }
      greetUser();  // Output: "Hello, Guest!"
  • Rest Parameters: Collect multiple arguments into a single array.

    • Example:

      function sum(...numbers) {
          return numbers.reduce((acc, curr) => acc + curr, 0);
      }
      console.log(sum(1, 2, 3, 4));  // Output: 10

Return Values

  • Returning Values: Functions can return values using the return statement.

    • Example:

      function multiply(a, b) {
          return a * b;
      }
      let result = multiply(5, 4);
      console.log(result);  // Output: 20
  • Return Without Value: If no return is specified, the function returns undefined.

    • Example:

      function noReturn() {
          console.log("This function has no return value.");
      }
      console.log(noReturn());  // Output: "This function has no return value." followed by `undefined`

Scope in JavaScript

Types of Scope

  • Global Scope: Variables declared outside of any function, accessible anywhere in the code.

    • Example:

      let globalVar = "I am a global variable";
      function showGlobalVar() {
          console.log(globalVar);  // Accessible anywhere
      }
      showGlobalVar();
  • Local Scope: Variables declared inside a function, accessible only within that function.

    • Example:

      function localScopeExample() {
          let localVar = "I am a local variable";
          console.log(localVar);  // Accessible only inside this function
      }
      localScopeExample();
      // console.log(localVar);  // Error: localVar is not defined

Block Scope

  • Block Scope: Variables declared with let or const inside {} are scoped to that block.

    • Example:

      if (true) {
          let blockScopedVar = "I am block scoped";
          console.log(blockScopedVar);  // Accessible here
      }
      // console.log(blockScopedVar);  // Error: blockScopedVar is not defined
  • var Scope Exception: Variables declared with var are function-scoped, not block-scoped.

    • Example:

      if (true) {
          var functionScopedVar = "I am function scoped";
      }
      console.log(functionScopedVar);  // Output: "I am function scoped"

Lexical Scope and Closures

  • Lexical Scope: Refers to the ability for a function to access variables from the parent scope in which it was defined.

    • Example:

      function outerFunction() {
          let outerVar = "I am an outer variable";
          function innerFunction() {
              console.log(outerVar);  // Accessible due to lexical scope
          }
          innerFunction();
      }
      outerFunction();  // Output: "I am an outer variable"
  • Closures: Functions that remember the environment in which they were created, even after the outer function has finished executing.

    • Example:

      function createCounter() {
          let count = 0;
          return function() {
              count++;
              return count;
          };
      }
      const counter = createCounter();
      console.log(counter());  // Output: 1
      console.log(counter());  // Output: 2
    • Use Cases for Closures: Closures are useful for data privacy and creating functions with preserved data.

      • Example: Creating a private counter that cannot be directly modified from outside its scope.

Arrow Functions vs Regular Functions

  • this Keyword: Arrow functions do not have their own this context, they inherit this from the enclosing scope.

    • Example:

      function RegularFunctionExample() {
          this.value = 10;
          setTimeout(function() {
              console.log(this.value);  // Output: undefined (function context)
          }, 1000);
      }
      new RegularFunctionExample();
      
      function ArrowFunctionExample() {
          this.value = 10;
          setTimeout(() => {
              console.log(this.value);  // Output: 10 (lexical context)
          }, 1000);
      }
      new ArrowFunctionExample();
  • Arrow Functions as Methods: Avoid using arrow functions as methods within objects since they do not bind this.

    • Example:

      const obj = {
          value: 42,
          regularMethod() {
              console.log(this.value);  // Output: 42
          },
          arrowMethod: () => {
              console.log(this.value);  // Output: undefined (lexical context)
          }
      };
      obj.regularMethod();
      obj.arrowMethod();

Immediately Invoked Function Expressions (IIFE)

  • IIFE: A function that runs as soon as it is defined.

    • Syntax:

      (function() {
          console.log("This is an IIFE");
      })();
    • Use Case: Useful for creating a private scope to avoid polluting the global namespace, often used in module patterns.

  • IIFE with Parameters: You can pass arguments into an IIFE.

    • Example:

      (function(message) {
          console.log(message);
      })("Hello from IIFE with parameters!");
      // Output: "Hello from IIFE with parameters!"

Summary

  • Functions: Essential for reusable code. Learn to use function declarations, expressions, arrow functions, and understand their nuances like hoisting.

  • Scope: Understand the difference between global, local, block scope, and how lexical scope impacts functions. Closures are powerful for preserving state and ensuring data privacy.

  • this Keyword: Arrow functions inherit this, while regular functions have their own this context. Use caution when using this in different function types.

  • IIFE: A way to create immediate private scopes to keep code modular and avoid global pollution.


Next Chapter: Advanced JavaScript Concepts

Previous2 - BasicsNext4 - Advanced Concepts

Last updated 6 months ago