函数只有在调用时,才会执行。
通过函数名称进行调用(可以在声明之前调用,也可以在声明之后调用)。
函数名后带括号时表示调用;不带括号时,表示这个函数本身。
函数也是一种数据类型,可以当做变量进行处理。
JavaScript是一种基于对象的脚本语言,所有的函数都是基于对象的操作方式。
函数的声明
JavaScript 使用关键字 function 声明(定义)函数。
注意:在 JavaScript 中,无论是变量、函数还是关键字,都严格区分大小写。
基本用法
声明一个函数时,可以给多个参数,但不能有默认值。
function foo(a){ console.log(typeof(a)); }var a=[1,2]; foo(a);
函数表达式
函数也可以通过一个表达式来声明,函数表达式可以存储在变量中。
var x = function (a, b) {return a * b};console.log( x(3,4) );
上面的函数是一个匿名函数,函数存储在变量中,不需要函数名称,通常通过变量名来调用。
Function() 构造函数
函数也可以通过内置的 JavaScript 函数构造器 Function() 来声明。
var foo = new Function("a", "b", "return a * b"); console.log( foo(4,5) );
函数自调用
在声明函数的同时,通过括号包括起来,进行函数的自调用。
(function() { var a=5; console.log(a);})();
上面的函数是匿名函数,非匿名函数也适用函数的自调用。
函数内部的 arguments 对象
在函数体内,arguments 对象代表函数调用时,传入的参数。
function foo(a, b) { return arguments };console.log( foo(3, 4) );// 输出: { '0': 3, '1': 4 }
模拟函数重载
用 arguments 对象判断传递给函数的参数个数,即可模拟函数重载:
function foo() { if(arguments.length == 1) { console.log(arguments[0]); } else if(arguments.length == 2) { console.log(arguments[0] + arguments[1]); } } foo(10); // 输出:10foo(10, 20); // 输出:30
闭包
在 JavaScript 中,变量分为全局变量和局部变量。
全局变量:在函数外部声明的变量,作用域是全局的。
局部变量:在函数内部声明的变量,只在函数内部可访问,生命周期是从变量声明到函数调用结束。
在 PHP 中,有一种 static 静态变量,函数调用时,只会初始化一次,并将 static 变量保存在内存中。像这种将函数中的变量静态化的方式,在 JavaScript 中该如何实现?
在 JavaScript 中,并没有 static 变量,但可以通过闭包的方式来实现类似的功能。
来看一个计数器的例子:
var add = (function () { // 外层函数 var counter = 0; // 局部变量 counter return function () { // 内层函数 return counter += 1; } })(); console.log( add() ) ; // 输出:1console.log( add() ) ; // 输出:2console.log( add() ) ; // 输出:3
这里,外层函数自调用后,声明了一个局部变量 counter,并赋予初始值 0;然后,返回内层函数,并且,在内层函数中使用了 counter。
这样,对于 add() 函数来说,无论调用多少次,counter 变量都只会初始化一次,而且 counter 仅在函数内部可见,不会被外部污染。这个就叫做 JavaScript 闭包。它使得函数拥有静态变量成为可能。
JavaScript 闭包 的定义:
即使外层函数关闭,仍然可访问外层函数内部的局部变量的内层函数,就叫做闭包。
这里,闭包包含两层含义:
闭包是嵌套函数中的内层函数。
就算外层函数关闭了,闭包仍然可以访问外层函数中的局部变量。