现在位置: 首页 > Node.js 教程 > 正文

Node.js 函数

在 Node.js 中,函数是 JavaScript 的核心组成部分之一,用于封装和执行特定任务。

Node.js 继承了 JavaScript 的所有函数特性,并在其异步编程模型中发挥了重要作用。

在 JavaScript中,一个函数可以作为另一个函数的参数。我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数。

函数声明

使用 function 关键字声明一个函数。

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

函数表达式

将函数赋值给一个变量。

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

箭头函数

ES6 引入的简洁函数表达式。

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

// 单行箭头函数
const greet = name => console.log(`Hello, ${name}!`);

函数的类型

1、普通函数

最常见的函数形式,可以有参数和返回值。

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

2、匿名函数

没有名字的函数,通常作为参数传递给其他函数。

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

3、回调函数

作为参数传递给另一个函数,并在某个操作完成后被调用。

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

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

异步函数

使用 async 和 await 关键字处理异步操作。

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));

高级用法

1、闭包

闭包是指一个函数能够记住并访问其词法作用域,即使这个函数在其词法作用域之外执行。

实例

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

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

2、高阶函数

接受函数作为参数或返回函数的函数。

实例

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 greet(name = 'Guest') {
    console.log(`Hello, ${name}!`);
}

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

剩余参数

允许将不定数量的参数表示为一个数组。

实例

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

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

解构参数

从对象或数组中提取数据并将其赋值给变量。

实例

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

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

实例

函数单一职责:每个函数应该只做一件事,这样更容易测试和维护。

实例

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

避免全局变量:尽量减少全局变量的使用,使用局部变量和函数参数。

实例

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

使用箭头函数:箭头函数简洁明了,特别是在处理回调函数时。

实例

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

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

错误处理: 使用 try...catch 语句处理可能抛出的错误。

实例

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);
    }
}

函数作为参数: 函数作为一个参数来使用。

实例

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

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

execute(say, "Hello");

以上代码中,我们把 say 函数作为 execute 函数的第一个变量进行了传递。这里传递的不是 say 的返回值,而是 say 本身!

这样一来, say 就变成了execute 中的本地变量 someFunction ,execute 可以通过调用 someFunction() (带括号的形式)来使用 say 函数。

当然,因为 say 有一个变量, execute 在调用 someFunction 时可以传递这样一个变量。

匿名函数:我们可以把一个函数作为变量传递。但是我们不一定要绕这个"先定义,再传递"的圈子,我们可以直接在另一个函数的括号中定义和传递这个函数:

实例

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

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

我们在 execute 接受第一个参数的地方直接定义了我们准备传递给 execute 的函数。

用这种方式,我们甚至不用给这个函数起名字,这也是为什么它被叫做匿名函数 。


函数传递是如何让 HTTP 服务器工作的

带着这些知识,我们再来看看我们简约而不简单的HTTP服务器:

实例

var http = require("http");

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

现在它看上去应该清晰了很多:我们向 createServer 函数传递了一个匿名函数。

用这样的代码也可以达到同样的目的:

实例

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);