# Mastering JavaScript: Functions & Strict Mode

Understanding functions and the nuances of strict mode in JavaScript is essential for writing efficient, clean, and maintainable code. This comprehensive guide covers everything from defining and calling functions to advanced topics like closures, lexical scoping, and recursion, ensuring you have a thorough grasp of these crucial concepts.

## Functions

Functions are one of the fundamental building blocks in JavaScript. A function is a block of code designed to perform a particular task, which is executed when "called" or "invoked".

### Defining and Calling Functions

You can define a function using a function declaration or a function expression.

**Function Declaration:**

```javascript
function greet(name) {
  return `Hello, ${name}!`;
}

console.log(greet('Alice')); // "Hello, Alice!"
```

**Function Expression:**

```javascript
const greet = function(name) {
  return `Hello, ${name}!`;
};

console.log(greet('Bob')); // "Hello, Bob!"
```

**Named Function Expression:** A named function expression has a name property that is useful for recursion and debugging.

```javascript
const factorial = function fact(n) {
  if (n <= 1) return 1;
  return n * fact(n - 1);
};

console.log(factorial(5)); // 120
```

### Function Parameters

Functions can take parameters (arguments) to work with.

**Default Parameters:** You can provide default values for parameters.

```javascript
function greet(name = 'Guest') {
  return `Hello, ${name}!`;
}

console.log(greet()); // "Hello, Guest!"
console.log(greet('Alice')); // "Hello, Alice!"
```

**Rest Parameters:** Rest parameters allow you to represent an indefinite number of arguments as an array.

```javascript
function sum(...numbers) {
  return numbers.reduce((acc, val) => acc + val, 0);
}

console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5, 6, 7)); // 22
```

### Arrow Functions

Arrow functions provide a shorthand syntax for writing function expressions and do not have their own `this` context.

**Syntax and Examples:**

```javascript
const greet = (name) => `Hello, ${name}!`;

console.log(greet('Alice')); // "Hello, Alice!"

const add = (a, b) => a + b;
console.log(add(5, 3)); // 8

// Single parameter without parentheses
const square = x => x * x;
console.log(square(4)); // 16

// No parameters
const sayHello = () => 'Hello!';
console.log(sayHello()); // "Hello!"
```

### IIFEs (Immediately Invoked Function Expressions)

An IIFE is a function that runs as soon as it is defined.

**Syntax and Examples:**

```javascript
(function() {
  console.log('This is an IIFE');
})();

(() => {
  console.log('This is an arrow function IIFE');
})();
```

![Modern JavaScript be like : r/ProgrammerHumor](https://i.redd.it/aj6eilme6wf31.jpg align="center")

### arguments Object

The `arguments` object is an array-like object accessible inside functions that contains the values of the arguments passed to that function.

**Examples:**

```javascript
function sum() {
  let total = 0;
  for (let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}

console.log(sum(1, 2, 3)); // 6
console.log(sum(4, 5, 6, 7)); // 22
```

### Scope & Function Stack

Understanding scope is critical to managing variables and memory. Scope determines the accessibility of variables. JavaScript has function scope and block scope.

#### Function Scope

Variables defined inside a function are not accessible from outside the function.

```javascript
function greet() {
  let name = 'Alice';
  console.log(`Hello, ${name}`);
}

greet(); // "Hello, Alice"
// console.log(name); // Error: name is not defined
```

#### Block Scope

Introduced in ES6, `let` and `const` allow you to declare variables with block scope.

```javascript
{
  let x = 10;
  const y = 20;
  console.log(x); // 10
  console.log(y); // 20
}

// console.log(x); // Error: x is not defined
// console.log(y); // Error: y is not defined
```

#### Recursion

A function can call itself, which is known as recursion. This is useful for tasks that can be divided into similar subtasks.

**Example:**

```javascript
function factorial(n) {
  if (n === 0) {
    return 1;
  }
  return n * factorial(n - 1);
}

console.log(factorial(5)); // 120
```

![Infinite loops sneak up on all of us, even Gru – ProgrammerHumor.io](https://programmerhumor.io/wp-content/uploads/2022/04/programmerhumor-io-javascript-memes-python-memes-d378e7efe6b221a-758x468.jpg align="center")

#### Lexical Scoping

JavaScript uses lexical scoping, meaning the accessibility of variables is determined by their position in the source code.

**Example:**

```javascript
function outerFunction() {
  let outerVariable = 'I am outside!';

  function innerFunction() {
    console.log(outerVariable); // "I am outside!"
  }

  innerFunction();
}

outerFunction();
```

#### Closures

A closure is a function that has access to its own scope, the scope of the outer function, and the global scope.

**Example:**

```javascript
function outerFunction() {
  let outerVariable = 'I am outside!';

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

const inner = outerFunction();
inner(); // "I am outside!"
```

![How Do Closures and Hoisting Work in JavaScript Under the Hood? | by Vidip  Malhotra | JavaScript in Plain English](https://miro.medium.com/v2/resize:fit:650/1*gg3maLFZdaoMej_fU4jWmA.jpeg align="center")

### Built-in Functions

JavaScript provides a variety of built-in functions for different tasks.

**Examples:**

```javascript
console.log(parseInt('10')); // 10
console.log(parseFloat('10.5')); // 10.5
console.log(isNaN('Hello')); // true
console.log(isFinite(10)); // true

// String functions
let str = 'Hello World!';
console.log(str.length); // 12
console.log(str.toUpperCase()); // "HELLO WORLD!"
console.log(str.toLowerCase()); // "hello world!"
console.log(str.indexOf('World')); // 6

// Array functions
let arr = [1, 2, 3, 4, 5];
console.log(arr.length); // 5
console.log(arr.push(6)); // 6 (new length)
console.log(arr.pop()); // 6 (removed element)
console.log(arr.join('-')); // "1-2-3-4-5"
```

![20 Funny JavaScript Memes. Come in, we have memes ahead. | by Ariana  Milasincic | JavaScript in Plain English](https://miro.medium.com/v2/resize:fit:1280/0*gUmnBbPXyTNTL8hI align="center")

## Strict Mode

Strict mode is a way to opt into a restricted variant of JavaScript, which eliminates some silent errors, improves performance, and makes debugging easier.

![Strict Mode For Filthy Code. I think Javascript is downright filthy… | by  Trevor Jameson | Medium](https://miro.medium.com/v2/resize:fit:960/1*57z0QdqKgE5wUETPk0ToSw.gif align="center")

### Enabling Strict Mode

To enable strict mode for an entire script, place `"use strict";` at the top of the script.

**Example:**

```javascript
"use strict";

x = 3.14; // Error: x is not defined
```

### Benefits of Strict Mode

1. **Eliminates**`this` coercion:
    
    ```javascript
    "use strict";
    function logThis() {
      console.log(this);
    }
    logThis(); // undefined
    ```
    
2. **Disallows duplicate property names or parameter values:**
    
    ```javascript
    "use strict";
    const obj = {
      prop: 1,
      prop: 2 // Error: Duplicate data property in object literal not allowed in strict mode
    };
    ```
    
3. **Catches common coding bloopers:**
    
    ```javascript
    "use strict";
    let obj = { get x() { return 0; } };
    obj.x = 3.14; // Error: Cannot set property x of #<Object> which has only a getter
    ```
    
4. **Prevents the use of**`with` statement:
    
    ```javascript
    "use strict";
    with (obj) { // Error: Strict mode code may not include a with statement
      // do something
    }
    ```
    

### Strict Mode in Functions

You can also enable strict mode only for specific functions.

**Example:**

```javascript
function strictFunction() {
  "use strict";
  // Function-level strict mode syntax
  let x = 3.14; // Error: x is not defined
}

function nonStrictFunction() {
  let x = 3.14; // This is fine
}
```

## Conclusion

Mastering functions and understanding strict mode are essential skills in JavaScript. Functions provide modularity and reusability in your code, while strict mode helps catch errors early and enforce best practices. By leveraging function parameters, arrow functions, IIFEs, and closures, you can write cleaner, more efficient code. Understanding scope, recursion, and built-in functions further enhances your ability to write robust JavaScript applications. With this comprehensive knowledge, you will be well-equipped to handle any function-related challenges and write secure, error-free code using strict mode.

As you continue to deepen your understanding of JavaScript, it's crucial to grasp how the `this` keyword operates in various contexts. In the next article, we will explore the intricacies of `this` in JavaScript, covering scenarios like function borrowing, methods, standalone functions, event handlers, and more. Understanding `this` will empower you to write more effective and bug-free code. Stay tuned!

%%[bmc-singhlify]
