函数是这一章的主角。学会它,你写的脚本就不用再把同一段代码抄来抄去了。
return 把结果交回去
默认参数:不传就用备好的值
作用域:变量能用的范围
回调:把函数交给别人事后调用
闭包:函数记住出生时的变量
先记住一句话:函数就是把一段逻辑打包成一个“命令”,起个名字,以后反复调用。就像遥控器上的一个按钮——按一下,就执行那一整套动作,不用每次都从头操作。
最经典的写法,用 function 开头(这个词就当固定写法背下来,意思是“下面要定义一个函数”):
function add(a, b) { // 定义函数 add,它接收两个数 a 和 b
return a + b; // return:把算出的结果交回去
}
add(1, 2); // 调用它,结果是 3
return 是“把结果交回去”。函数里没有写 return,调用它得到的就是 undefined(意思是“没有值”)——这是新手最常踩的坑,第四节练习里还会再考。箭头函数是更短的写法,靠一个箭头 => 认出它。它在回调里到处都是,先混个脸熟:
const add2 = (a, b) => a + b; // 和上面的 add 一模一样,只是写法更短 add2(1, 2); // 结果也是 3
注意:一行版的箭头函数,箭头后面写的东西直接就是返回值,不用再写 return。
再看一个带默认参数的例子——参数可以提前备好一个值,不传的时候就用它:
const greet = (name = "朋友") => { // name 不传时,默认是 "朋友"
return `你好,${name}`; // ${name}:把 name 的值填进这句话里
};
greet(); // 没传名字,结果是 "你好,朋友"
greet("cc"); // 传了名字,结果是 "你好,cc"
{ } 花括号就像一间屋子:用 let / const 在屋子里定义的变量,只在这间屋子里有效,出了门就找不到了。
let 外面的 = "我站门外"; // 在所有花括号外面 function 看一看() { let 里面的 = "我在屋里"; console.log(外面的); // ✅ 函数内部能看到外部变量 } console.log(里面的); // ❌ 报错!外部看不到函数内部的变量
记法:里面能看外面,外面看不见里面。
函数不光能自己调用,还能当成参数传给别人,让别人在合适的时机替你调用——这种被传进去的函数,就叫回调。就像你留个电话给快递员:“包裹到了你打给我”,打不打、什么时候打,是他决定的。
// 长相一:数组的 map 逐个处理每个元素,箭头函数就是回调 list.map(x => x * 2); // 长相二:网络请求完成后再执行的回调(Surge / Loon 脚本里天天见) $httpClient.get(url, (err, resp, data) => { // 请求结束、数据回来之后,才会执行到这里 });
记住:看到函数被塞进另一个函数的括号里,十有八九就是回调。
闭包说的是:一个函数会“记住”它出生时身边的变量,哪怕后来离开了那个地方,记忆还在。这个概念现在不用深究,先留个印象——以后写 Cloudflare Workers(云端小程序)时你会自然地遇到它,到时再回头看就懂了。
下面的代码可以直接改(改数字、改名字、改运算符号都行),改完点“运行”,页面会按你写的代码一步步算给你看,结果显示在下方。
函数声明和箭头函数各算一次 1 + 2,对比结果。
一次不传名字,一次传 "cc",看看默认参数是怎么兜底的。
map 会拿着数组里的每个数字,逐个去调用你给的箭头函数。
选一段本章的代码(或者把你自己遇到的代码粘进来),点“逐行拆解”,每一行都会配上中文说明:括号里是什么、参数是什么、英文词是什么意思。
你的 Telegram 机器人要给很多人发到期提醒:3 天后到期提醒一次、1 天后到期再提醒一次、到期当天还提醒一次。如果不包成函数,这段发送逻辑就得抄三遍,改一处要改三个地方。包成函数后,一处定义、到处调用:
function 发提醒(谁, 内容) { // 把"发提醒"打包成一个命令
// ……这里是真正发送消息的那几行……
}
发提醒("张三", "会员 3 天后到期"); // 调用一次
发提醒("李四", "会员今天到期"); // 再调用一次,不用重写
Surge、Loon 的脚本只要上网拿数据,基本都长这样。第二个参数就是一个箭头函数回调:请求发出后先干别的,数据回来时平台才调用它,把结果塞进 err(错误)、resp(响应头)、data(正文)三个参数里:
$httpClient.get(url, (err, resp, data) => {
// 这一段不会立刻执行,要等数据回来才被调用——这就是回调
if (err) {
console.log("请求出错了");
} else {
console.log("拿到数据了:", data);
}
});
以后再在脚本里看到 => { ... } 被塞在括号里,你就知道:哦,这是留给平台“事后打的电话”。
写 Cloudflare Workers(云端小程序)时经常会遇到这种代码:外层函数准备好一些变量,内层函数接着用——内层函数记住了外层变量,这就是闭包在干活。现在完全不用写出来,记住“函数会记住出生时的变量”这一句,等真写的时候再回来对照,会一下子通。
函数就是把逻辑打包成一个能反复调用的“命令”:return 负责交结果,箭头函数是它的简写,回调是把它交给别人事后调用,闭包是它记住了出生时的变量。
JavaScript 从零开始 · 第六章《函数》交互版