Functions

If you're coming from a Python background, you're likely already familiar with the concept of functions - reusable blocks of code designed to perform a certain task. JavaScript functions operate on the same principle but with some differences in terms of syntax and behavior. Let's delve into it.

Function Declaration

In JavaScript, a function can be declared using the function keyword:

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

To call this function, you would use greet().

This is equivalent to the following Python code:

def greet():
    print("Hello, world!")

And similarly, you'd call it using greet().

Parameters and Arguments

Like Python, JavaScript functions can take parameters and be called with arguments. However, JavaScript is more lenient with argument count mismatch:

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

greet("Alice");
greet(); // This is allowed in JavaScript

In this case, calling greet() with no arguments logs "Hello, undefined".

Return Values

JavaScript functions, like their Python counterparts, can return a value using the return statement:

function add(x, y) {
    return x + y;
}

let sum = add(5, 3);
console.log(sum); // 8

If a JavaScript function doesn't have a return statement, it returns undefined.

Function Expressions

JavaScript has a concept called function expressions, where a function is assigned to a variable:

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

greet("Alice");

Function expressions can be anonymous (function without name), as seen above, or named (function with name).

Arrow Functions

Introduced in ES6, arrow functions provide a more compact syntax for function expressions:

let greet = (name) => {
    console.log("Hello, " + name);
};

greet("Alice");

If there's only one parameter, you can omit the parentheses:

let greet = name => {
    console.log("Hello, " + name);
};

If the function body only contains one statement, you can omit the curly braces and the return keyword:

let add = (x, y) => x + y;

let sum = add(5, 3);
console.log(sum); // 8

Callback Functions

JavaScript heavily uses callback functions, which are functions passed as arguments to other functions. Callbacks are often used in event handling and asynchronous operations.

function greet(callback) {
    console.log("Hello, world!");
    callback();
}

greet(function() {
    console.log("This runs after the greet function.");
});

// logs:
// Hello, world!
// This runs after the greet function.

Closure

JavaScript functions create their own scope for variables – they can access their own local variables, variables from their parent (enclosing) scope, and global variables. This capability to remember and access its lexical scope even when the function is executing outside its lexical scope is known as closure.

function makeGreetingFunction(name) {
    let message = "Hello, " + name + "!";
    return function() {
        console.log(message);
    };
}

let greetAlice = makeGreetingFunction("Alice");
greetAlice(); // "Hello, Alice!"

If it's a bit abstract, this video might be helpful, to elaborate what a closure is and how to use it.