企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 一、概述 函数是一段可以反复调用的代码块。函数还能接受输入的参数,不同的参数会返回不同的值。 ### 1.1 函数的声明 JavaScript 有三种声明函数的方法。 * function 命令 `function`命令声明的代码区块,就是一个函数。`function`命令后面是函数名,函数名后面是一对圆括号,里面是传入函数的参数。函数体放在大括号里面。 ~~~ function print(s) { console.log(s); } ~~~ 上面的代码命名了一个`print`函数,以后使用`print()`这种形式,就可以调用相应的代码。这叫做函数的声明(Function Declaration)。 * 函数表达式 除了用`function`命令声明函数,还可以采用变量赋值的写法。 ~~~ var print = function(s) { console.log(s); }; ~~~ 这种写法将一个匿名函数赋值给变量。这时,这个匿名函数又称函数表达式(Function Expression),因为赋值语句的等号右侧只能放表达式。 * Function 构造函数 第三种声明函数的方式是`Function`构造函数。 ~~~ var add = new Function( 'x', 'y', 'return x + y' ); // 等同于 function add(x, y) { return x + y; } ~~~ 上面代码中,`Function`构造函数接受三个参数,除了最后一个参数是`add`函数的“函数体”,其他参数都是`add`函数的参数。 ### 1.2 函数的重复声明 如果同一个函数被多次声明,后面的声明就会覆盖前面的声明。 ~~~ function f() { console.log(1); } f() // 2 function f() { console.log(2); } f() // 2 ~~~ ### 1.3 圆括号运算符,return 语句和递归 调用函数时,要使用圆括号运算符。圆括号之中,可以加入函数的参数。 ~~~ function add(x, y) { return x + y; } add(1, 1) // 2 ~~~ 函数体内部的`return`语句,表示返回。JavaScript 引擎遇到`return`语句,就直接返回`return`后面的那个表达式的值,后面即使还有语句,也不会得到执行。也就是说,`return`语句所带的那个表达式,就是函数的返回值。`return`语句不是必需的,如果没有的话,该函数就不返回任何值,或者说返回`undefined`。 函数可以调用自身,这就是递归(recursion)。下面就是通过递归,计算斐波那契数列的代码。 ~~~ function fib(num) { if (num === 0) return 0; if (num === 1) return 1; return fib(num - 2) + fib(num - 1); } fib(6) // 8 ~~~ 上面代码中,`fib`函数内部又调用了`fib`,计算得到斐波那契数列的第6个元素是8。 ### 1.4 函数名的提升 JavaScript 引擎将函数名视同变量名,所以采用`function`命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。所以,下面的代码不会报错。 ~~~ f(); function f() {} ~~~ 表面上,上面代码好像在声明之前就调用了函数`f`。但是实际上,由于“变量提升”,函数`f`被提升到了代码头部,也就是在调用之前已经声明了。但是,如果采用赋值语句定义函数,JavaScript 就会报错。 ~~~ f(); var f = function (){}; // TypeError: undefined is not a function // 等价于 var f; f(); f = function () {}; ~~~ ~~~ var f = function () { console.log('1'); } function f() { console.log('2'); } f() // 1 ~~~ ## 二、函数作用域 作用域(scope)指的是变量存在的范围。在 ES5 的规范中,JavaScript 只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。 * 对于顶层函数来说,函数外部声明的变量就是全局变量(global variable),它可以在函数内部读取。 ~~~ var v = 1; function f() { console.log(v); } f() // 1 ~~~ 上面的代码表明,函数`f`内部可以读取全局变量`v`。 * 在函数内部定义的变量,外部无法读取,称为“局部变量”(local variable)。 ~~~ function f(){ var v = 1; } v // ReferenceError: v is not defined ~~~ 上面代码中,变量`v`在函数内部定义,所以是一个局部变量,函数之外就无法读取。 函数内部定义的变量,会在该作用域内覆盖同名全局变量。 ~~~ var v = 1; function f(){ var v = 2; console.log(v); } f() // 2 v // 1 ~~~ 上面代码中,变量`v`同时在函数的外部和内部有定义。结果,在函数内部定义,局部变量`v`覆盖了全局变量`v`。 ## 三、参数 函数运行的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参数。 ~~~ function square(x) { return x * x; } square(2) // 4 square(3) // 9 ~~~ 上式的`x`就是`square`函数的参数。每次运行的时候,需要提供这个值,否则得不到结果。