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、闭包
闭包是指一个函数能够记住并访问其词法作用域,即使这个函数在其词法作用域之外执行。
实例
let count = 0;
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
2、高阶函数
接受函数作为参数或返回函数的函数。
实例
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!
剩余参数
允许将不定数量的参数表示为一个数组。
实例
return numbers.reduce((acc, num) => acc + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
解构参数
从对象或数组中提取数据并将其赋值给变量。
实例
console.log(`Name: ${name}, Age: ${age}`);
}
const user = { name: 'Alice', age: 30 };
getUserInfo(user); // Name: Alice, Age: 30
实例
函数单一职责:每个函数应该只做一件事,这样更容易测试和维护。
实例
return width * height;
}
避免全局变量:尽量减少全局变量的使用,使用局部变量和函数参数。
实例
let total = 0;
for (const item of items) {
total += item.price * item.quantity;
}
return total;
}
使用箭头函数:箭头函数简洁明了,特别是在处理回调函数时。
实例
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
];
const names = users.map(user => user.name);
console.log(names); // ['Alice', 'Bob']
错误处理: 使用 try...catch 语句处理可能抛出的错误。
实例
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);
}
}
函数作为参数: 函数作为一个参数来使用。
实例
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 时可以传递这样一个变量。
匿名函数:我们可以把一个函数作为变量传递。但是我们不一定要绕这个"先定义,再传递"的圈子,我们可以直接在另一个函数的括号中定义和传递这个函数:
实例
someFunction(value);
}
execute(function(word){ console.log(word) }, "Hello");
我们在 execute 接受第一个参数的地方直接定义了我们准备传递给 execute 的函数。
用这种方式,我们甚至不用给这个函数起名字,这也是为什么它被叫做匿名函数 。
函数传递是如何让 HTTP 服务器工作的
带着这些知识,我们再来看看我们简约而不简单的HTTP服务器:
实例
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
现在它看上去应该清晰了很多:我们向 createServer 函数传递了一个匿名函数。
用这样的代码也可以达到同样的目的:
实例
function onRequest(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}
http.createServer(onRequest).listen(8888);