09函数

一、函数声明

使用 函数声明 创建函数。

function 关键字首先出现,然后是 函数名,然后是括号之间的 参数 列表(用逗号分隔,在上述示例中为空,我们将在接下来的示例中看到),最后是花括号之间的代码(即“函数体”)。

1
2
3
function name(parameter1, parameter2, ... parameterN) {
...body...
}

二、变量

在函数中声明的变量只在该函数内部可见,函数也可以访问外部变量。

函数对外部变量拥有全部的访问权限。函数也可以修改外部变量。

只有在没有局部变量的情况下才会使用外部变量。

如果在函数内部声明了同名变量,那么函数会 遮蔽 外部变量。例如,在下面的代码中,函数使用局部的 userName,而外部变量被忽略:

1
2
3
4
5
6
7
8
9
10
11
12
13
let userName = 'John';

function showMessage() {
let userName = "Bob"; // 声明一个局部变量

let message = 'Hello, ' + userName; // Bob
alert(message);
}

// 函数会创建并使用它自己的 userName
showMessage();

alert( userName ); // John,未被更改,函数没有访问外部变量。

任何函数之外声明的变量,例如上述代码中的外部变量 userName,都被称为 全局 变量。

全局变量在任意函数中都是可见的(除非被局部变量遮蔽)。

减少全局变量的使用是一种很好的做法。现代的代码有很少甚至没有全局变量。大多数变量存在于它们的函数中。但是有时候,全局变量能够用于存储项目级别的数据。

三、参数

我们可以通过参数将任意数据传递给函数。

这里还有一个例子:我们有一个变量 from,并将它传递给函数。请注意:函数会修改 from,但在函数外部看不到更改,因为函数修改的是复制的变量值副本:

1
2
3
4
5
6
7
8
9
10
11
12
13
function showMessage(from, text) {

from = '*' + from + '*'; // 让 "from" 看起来更优雅

alert( from + ': ' + text );
}

let from = "Ann";

showMessage(from, "Hello"); // *Ann*: Hello

// "from" 值相同,函数修改了一个局部的副本。
alert( from ); // Ann

如果一个函数被调用,但有参数(argument)未被提供,那么相应的值就会变成 undefined

我们可以使用 = 为函数声明中的参数指定所谓的“默认”(如果对应参数的值未被传递则使用)值:

1
2
3
4
5
function showMessage(from, text = "no text given") {
alert( from + ": " + text );
}

showMessage("Ann"); // Ann: no text given

现在如果 text 参数未被传递,它将会得到值 "no text given"

这里 "no text given" 是一个字符串,但它可以是更复杂的表达式,并且只会在缺少参数时才会被计算和分配。所以,这也是可能的:

1
2
3
4
function showMessage(from, text = anotherFunction()) {
// anotherFunction() 仅在没有给定 text 时执行
// 其运行结果将成为 text 的值
}

有些时候,将参数默认值的设置放在函数执行(相较更后期)而不是函数声明时,也行得通。

我们可以通过将参数与 undefined 进行比较,来检查该参数是否在函数执行期间被传递进来:

1
2
3
4
5
6
7
8
9
10
11
function showMessage(text) {
// ...

if (text === undefined) { // 如果参数未被传递进来
text = 'empty message';
}

alert(text);
}

showMessage(); // empty message

……或者我们可以使用 || 运算符:

1
2
3
4
5
function showMessage(text) {
// 如果 text 为 undefined 或者为假值,那么将其赋值为 'empty'
text = text || 'empty';
...
}

现代 JavaScript 引擎支持空值合并运算符??,它在大多数假值(例如 0)应该被视为“正常值”时更具优势:

1
2
3
4
5
6
7
8
function showCount(count) {
// 如果 count 为 undefined 或 null,则提示 "unknown"
alert(count ?? "unknown");
}

showCount(0); // 0
showCount(null); // unknown
showCount(); // unknown

四、返回值

函数可以将一个值返回到调用代码中作为结果。

指令 return 可以在函数的任意位置。当执行到达时,函数停止,并将值返回给调用代码(分配给上述代码中的 result)。

只使用 return 但没有返回值也是可行的。但这会导致函数立即退出。

例如:

1
2
3
4
5
6
7
8
function showMovie(age) {
if ( !checkAge(age) ) {
return;
}

alert( "Showing you the movie" ); // (*)
// ...
}

在上述代码中,如果 checkAge(age) 返回 false,那么 showMovie 将不会运行到 alert

空值的 return 或没有 return 的函数返回值为 undefined

五、函数命名

函数就是行为(action)。所以它们的名字通常是动词。它应该简短且尽可能准确地描述函数的作用。这样读代码的人就能清楚地知道这个函数的功能。

一种普遍的做法是用动词前缀来开始一个函数,这个前缀模糊地描述了这个行为。团队内部必须就前缀的含义达成一致。

例如,以 "show" 开头的函数通常会显示某些内容。

函数以 XX 开始……

  • "get…" —— 返回一个值,
  • "calc…" —— 计算某些内容,
  • "create…" —— 创建某些内容,
  • "check…" —— 检查某些内容并返回 boolean 值,等。

这类名字的示例:

1
2
3
4
5
showMessage(..)     // 显示信息
getAge(..) // 返回 age(gets it somehow)
calcSum(..) // 计算求和并返回结果
createForm(..) // 创建表单(通常会返回它)
checkPermission(..) // 检查权限并返回 true/false
Author

WaterNorth

Posted on

2025-08-24

Updated on

2025-08-24

Licensed under