函数
一. 概述
函数是⼀段可以反复调⽤的代码块。函数还能接受输⼊的参数,不同的参数会返回不同的值。
1. 函数的声明
- function 命令
function 命令声明的代码区块,就是⼀个函数。 function 命令后⾯是函数名,函数名后⾯
是⼀对圆括号,⾥⾯是传⼊函数的参数。函数体放在⼤括号⾥⾯。
function 函数名称 (参数:可选) {
函数体
}
function print(s) {
console.log(s);
}
上⾯的代码命名了⼀个 print 函数,以后使⽤ print() 这种形式,就可以调⽤相应的代码。这 叫做函数的声明(Function Declaration)。
- 函数表达式
定义:不以function开头的函数语句就是函数表达式。
- 匿名函数表达式
var myFunction = function() {
statements;
}
这种形式看起来好像是常规的变量赋值语句,即创建一个函数并将它赋值给变量myFunction。这种情况下创建的函数叫做匿名函数。因为function关键字后面没有标识符。
2. 命名函数表达式
var myFunction = function namedFunction() {
statements;
}
(1)命名函数表达式的好处是当我们遇到错误时,堆栈跟踪会显示函数名,容易寻找错误。
(2)函数表达式其实是“忽略”函数名称的,并且不可以使用函数名()这种形式调用函数。
namedFunction(); //namedFunction is not defined
myFunction();
- functon 构造函数
var add = new Function(
'x',
'y',
'return x + y'
);
// 等同于
// function add(x, y) {
// return x + y;
// }
上⾯代码中, Function 构造函数接受三个参数,除了最后⼀个参数是 add 函数的“函数体”,其 他参数都是 add 函数的参数。
2. 函数的重复声明
unction f() {
console.log(1);
}
f() // 2
function f() {
console.log(2);
}
f() // 2
3. 圆括号运算符,return 语句和递归
function add(x, y) {
return x + y;
}
add(1, 1) // 2
函数可以调⽤⾃⾝,这就是递归(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
4. 函数名的提升
JavaScript 引擎将函数名视同变量名,所以采⽤ function 命令声明函数时,整个函数会像变量声 明⼀样,被提升到代码头部。所以,下⾯的代码不会报错
f();
function f() {}
表⾯上,上⾯代码好像在声明之前就调⽤了函数 f 。但是实际上,由于“变量提升”,函数 f 被提 升到了代码头部,也就是在调⽤之前已经声明了。但是,如果采⽤赋值语句定义函数,JavaScript 就 会报错。
二. 函数作用域
作⽤域(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 在函数内部定义,所以是⼀个局部变量,函数之外就⽆法读取。函数内部定义的变量,会在该作⽤域内覆盖同名全局变量。
三. 参数
函数运⾏的时候,有时需要提供外部数据,不同的外部数据会得到不同的结果,这种外部数据就叫参
数。
function square(x) {
return x * x;
}
square(2) // 4
square(3) //
上式的 x 就是 square 函数的参数。每次运⾏的时候,需要提供这个值,否则得不到结果。