YouTip LogoYouTip

Nodejs Function

Node.js Functions

Functions are reusable blocks of code designed to perform specific tasks.

In Node.js, functions are a core component of JavaScript and serve as the fundamental building blocks for constructing applications.

Node.js inherits all the function features of JavaScript and plays a crucial role in its asynchronous programming model.

In JavaScript, a function can be passed as an argument to another function. We can define a function first and then pass it, or define the function directly where the argument is passed.

Importance of Functions

  • Code Reuse: Avoids rewriting the same logic.
  • Modularity: Breaks down complex problems into smaller functions.
  • Maintainability: Makes debugging and modifying independent functional units easier.

Function Declaration

Declare a function using the function keyword.

function greet(name) {
  console.log(`Hello, ${name}!`);
}

Function Expression

Assign a function to a variable.

const greet = function(name) {
  console.log(`Hello, ${name}!`);
};

Arrow Functions

A concise function expression introduced in ES6.

const greet = (name) => {
  console.log(`Hello, ${name}!`);
};

// Single-line arrow function
const greet = name => console.log(`Hello, ${name}!`);

Types of Functions

1. Regular Functions

The most common form of function, which can have parameters and return values.

function add(a, b) {
  return a + b;
}

2. Anonymous Functions

Functions without a name, typically passed as arguments to other functions.

setTimeout(function() {
  console.log('This is an anonymous function.');
}, 1000);

3. Callback Functions

Functions passed as arguments to another function and invoked after a certain operation completes.

function fetchData(callback) {
  setTimeout(() => {
    const data = 'Some data';
    callback(data);
  }, 1000);
}

fetchData((data) => {
  console.log(data);
});

Asynchronous Functions

From callbacks to Promises.

Example

function readFilePromise(path) {
  return new Promise((resolve, reject) => {
    fs.readFile(path, 'utf8', (err, data) => {
      if (err) reject(err);
      else resolve(data);
    });
  });
}

Handling asynchronous operations with async and await keywords.

Example

async function fetchUser(id) {
  try {
    const response = await fetch(`https://api.example.com/users/${id}`);
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('Error fetching user:', error);
  }
}

fetchUser(1).then(user => console.log(user));

Comparison of Invocation Methods

Invocation Method Example Characteristics
Direct Call greet('Alice') Most common method
Method Call obj.method() this points to the calling object
Constructor Call new Constructor() Creates a new instance
Indirect Call greet.call(null, 'Bob') Can change the this binding

Advanced Usage

1. Closures

A closure refers to a function that can remember and access its lexical scope, even when the function is executed outside that lexical scope.

Example

function createCounter() {
  let count = 0;
  return function() {
    count++;
    return count;
  };
}

const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2

2. Higher-Order Functions

Functions that accept functions as arguments or return functions.

Example

function applyOperation(a, b, operation) {
  return operation(a, b);
}

const sum = applyOperation(5, 3, (x, y) => x + y);
const product = applyOperation(5, 3, (x, y) => x * y);

console.log(sum); // 8
console.log(product); // 15

Function Parameter Handling

Default Parameters

Provide default values for parameters when declaring a function.

function greet(name = 'Guest') {
  console.log(`Hello, ${name}!`);
}

greet(); // Hello, Guest!
greet('Alice'); // Hello, Alice!

Rest Parameters

Allows representing an indefinite number of arguments as an array.

Example

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

console.log(sum(1, 2, 3, 4)); // 10

Destructuring Parameters

Extracts data from objects or arrays and assigns them to variables.

Example

function getUserInfo({ name, age }) {
  console.log(`Name: ${name}, Age: ${age}`);
}

const user = { name: 'Alice', age: 30 };
getUserInfo(user); // Name: Alice, Age: 30

Examples

Single Responsibility of Functions: Each function should do only one thing, making it easier to test and maintain.

Example

function calculateArea(width, height) {
  return width * height;
}

Avoid Global Variables: Minimize the use of global variables; use local variables and function parameters instead.

Example

function calculateTotal(items) {
  let total = 0;
  for (const item of items) {
    total += item.price * item.quantity;
  }
  return total;
}

Use Arrow Functions: Arrow functions are concise and clear, especially when handling callback functions.

Example

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' }
];

const names = users.map(user => user.name);
console.log(names); // ['Alice', 'Bob']

Error Handling: Use try...catch statements to handle potential errors.

Example

async function fetchUser(id) {
  try {
    const response = await fetch(`https://api.example.com/users/${id}`);
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    const user = await response.json();
    return user;
  } catch (error) {
    console.error('Error fetching user:', error);
  }
}

Functions as Arguments: A function can be used as an argument.

Example

function say(word) {
  console.log(word);
}

function execute(someFunction, value) {
  someFunction(value);
}

execute(say, "Hello");

In the code above, we pass the say function as the first argument to the execute function. What is passed here is not the return value of say, but say itself!

This way, say becomes the local variable someFunction inside execute, and execute can use the say function by calling someFunction() (with parentheses).

Of course, since say has a parameter, execute can pass such a variable when calling someFunction.

Anonymous Functions: We can pass a function as a variable. However, we don't necessarily have to go through the "define first, then pass" process; we can define and pass the function directly within the parentheses of another function:

Example

function execute(someFunction, value) {
  someFunction(value);
}

execute(function(word) { console.log(word); }, "Hello");

We define the function we intend to pass to execute directly where execute accepts the first argument.

In this way, we don't even need to give the function a name, which is why it's called an anonymous function.


How Function Passing Makes the HTTP Server Work

With this knowledge, let's look at our simple yet powerful HTTP server again:

Example

var http = require("http");

http.createServer(function(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}).listen(8888);

It should now be much clearer: we passed an anonymous function to the createServer function.

The same purpose can be achieved with this code:

Example

var http = require("http");

function onRequest(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}

http.createServer(onRequest).listen(8888);

Function Best Practices

Function Design Principles

  1. Single Responsibility: A function should do only one thing.
  2. Reasonable Naming: Use verb + noun format (e.g., getUserInfo).
  3. Control Length: It's recommended not to exceed 20 lines of code.
  4. Avoid Side Effects: Pure functions are easier to test and maintain.

Performance Optimization Tips

Example

// Use closures to cache results
function memoize(fn) {
  const cache = new Map();
  return (...args) => {
    const key = JSON.stringify(args);
    if (cache.has(key)) return cache.get(key);
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}

Practical Exercises

Exercise 1: Create a Temperature Conversion Function

Example

/**
 * Implement conversion between Celsius and Fahrenheit
 * @param {number} temp - Temperature value
 * @param {string} unit - Original unit ('C' or 'F')
 * @returns {number} Converted temperature
 */
function convertTemperature(temp, unit) {
  // Your code...
}

Exercise 2: Implement a Simple Event Emitter

Example

class EventEmitter {
  constructor() {
    this.events = {};
  }

  // Implement on/emit/off methods
}
← Csharp IntroNodejs Event β†’