函数和变量同样,能够在代码的任何地方定义。
JavaScript提供一些方式去定义方法:javascript
函数声明java
函数表达式express
函数做为另外一个函数结果被调用浏览器
基本建立函数的语法是函数声明。语法以下:函数
function f(arg1, arg2, ...) { ... code ... }
好比:spa
function sayHi(name) { alert("Hi, "+name) } sayHi('John')
这个例子声明一个只有一个参数的函数sayHi,运行sayHi。code
用return声明来返回值对象
function sum(a, b) { return a+b } var result = sum(2,5) alert(result)
若是函数没有返回值,结果被认为是一个特殊值“undefined”。以下例:递归
function getNothing() { // no return } var result = getNothing() alert(result)
返回空值也是同样结果:图片
function getNothing() { return } alert( getNothing() === undefined ) // true
函数内能够包含变量,用var来定义。这种变量叫作局部变量,只能被内部函数访问。
function sum(a, b) { var sum = a + b return sum }
建立一个函数min(a,b),接收两个数字,返回一个较小的值。
min(2, 5) == 2
min(3, -1) == -1
答案
方案一 用if判断:
function min(a, b) { if (a < b) { return a } else { return b } }
方案二 用三目运算符:
function min(a, b) { return a < b ? a : b // 若是是true运行a,不然运行b }
写一个函数pow(x,n)返回x的n次方,或者说,x被本身乘了n次。
pow(3, 2) = 3*3 = 9
pow(3, 3) = 333 = 27
pow(1, 100) = 11...*1 = 1
function(x,n){ var result for(var i = 0;i<n;i++){ result*=x; } return result; }
函数声明在预执行阶段(当浏览器准备执行代码)解析。因此函数声明在先后都能被调用到。
function sayHi(name) { alert("Hi, "+name) } sayHi("John")
sayHi("John") function sayHi(name) { alert("Hi, "+name) }
因此函数在任何位置均可以声明
好比,咱们可能但愿根据条件声明不一样的函数
sayHi() if (1) { function sayHi() { alert(1) } } else { function sayHi() { alert(2) } // <-- }
尝试在不一样浏览器中运行这个例子。火狐会报错,其余浏览器输出2。
那是由于声明在执行前被传递了。根据文档(p.10.5),后同名的函数,后
声明的会覆盖存在的函数。
当执行时,其余声明会被忽略,因此if语句没有任何效果。
函数表达式
JavaScript中函数是一等公民,和数字字符同样。
在任何你能够写值的地方,你均可以写函数。函数表达式的语法
function(arguments) { ... }
举例,你能够写
var f = 5
但你也能够赋函数表达式
var f = function(name) { alert("Hi, " + name + "!"); }
何时函数是表达式,何时是声明呢?
规则很简单。
但javascript解析器在主代码流中,他会认为这是函数声明。
当函数是声明语句的一部分是,他就是函数表达式。
当执行流到达函数表达式被建立,结果是,函数表达式只有他们被执行后才能使用。
var sayHi // sayHi() <-- 这里不能执行,尚未sayHi函数 if (1) { sayHi = function() { alert(1) } } else { sayHi = function() { alert(2) } } sayHi()
上述代码全部浏览器执行结果相同。
请用声明
经验不足的开发人员写的代码中,方法常常用表达式来声明:
var f = function() { ... }
函数声明更加可读简洁,仍是用函数声明吧。
function f() { ... }
除此之外,函数声明可在定义前调用。
只有你在执意要用函数表达式时采用。如例子中,条件性的函数定义。
函数是值
javascript中的函数是通常值,咱们能够输出他。
function f() { alert(1) } alert(f)
上面这个输出函数的例子。一般用做源代码。( Usually as the source code.)
Both declarations and expression declare a variable and put the function into it. Only the creation time is different.
声明和表达式均可以做为变量的值。只是建立的时间不一样。
传递函数
函数和任何值同样能够被赋值,作为其余函数的参数传递等。
以下例,怎么定义函数没有关系。
function sayHi(name) { alert("Hi, "+name) } var hi = sayHi // 把函数赋值给变量 hi("dude") // 执行函数
函数经过引用被赋值。函数保存在内存的某处,sayHi是它的引用(指向)。当我把函数赋值给hi,变量开始引用同一个函数。
一个函数能够接受另外一个函数作为参数
function runWithOne(f) { // 运行作为参数1的函数 f(1) } runWithOne( function(a){ alert(a) } )
逻辑上说,函数是一个动做.那么,传递函数是传递一个动做,可以在程序另外一部分来初始化。这种特性在javascript中被普遍使用。
在上面的例子中,咱们建立一个没有名字的函数,没有赋值给任何变量。这样的函数叫匿名函数。
就地执行
能够用函数表达式建立并当即运行函数,像这样:
(function() { var a, b // 局部变量 // ... // 其余代码 })()
当即执行函数大多被用在咱们想作一些围绕局部变量的事情。咱们不想咱们的局部变量变成全局,因此包含在函数里面。
在执行后,全局命名空间仍是很干净,很好的实践。
那为何函数在括号中?是由于javascript只容许函数表达式当即执行。
函数声明不能被这样用:
function work() { // ... }() // 语法错误
即便咱们去掉名称,javaScript会看到关键词函数,尝试转换成函数声明。
function() { // 错误,没有名称的函数声明。 // ... }()
那么。惟一的方式是把函数用括号包起来。就会打断他被认为是声明的一部分,因此是函数表达式。
若是函数是一个明显的表达式,那就不必包起来,以下:
var result = function(a,b) { return a+b }(2,2) alert(result) // 4
在上面的代码中,函数被建立且当即调用。
就像var result = sum(2,2),用sum函数替换函数表达式。
下面的代码执行结果是什么?为何?
var a = 5 (function() { alert(a) })()
答案:
答案是error,尝试下面代码:
var a = 5 (function() { alert(a) })()
在var a = 5后面没有分号。JavaScript把代码认为是:
var a = 5(function() { alert(a) })()
那么,他会尝试运行5作为一个函数,这就会形成错误。能运行的代码以下:
var a = 5; (function() { alert(a) })()
这可能JavaScript中是最危险隐蔽的不写分号。
还有一种方式直接调用函数构造器。把参数列表和函数做为字符串,用他们建立函数。
var sayHi = new Function('name', ' alert("Hi, "+name) '); sayHi("Benedict");
这种方式用的不多不多,几乎不用。
命名函数表达式
一个函数表达式可有名字:
var f = function sayHi(name) { alert("Hi, "+name) }
语法叫命名函数表达式(NFE)在任何浏览器均可用除了IE9如下。
在那些支持的浏览器中,名字只在函数内可见
var f = function sayHi(name) { alert(sayHi) // 输出函数 } alert(sayHi) // 错误:为定义的变量'sayHi'
在这种状况IE会建立两个函数对象:sayHi和f:
var f = function g() { } // IE中是false,其余浏览器报错(g为定义) alert(f=== g)
NEFS存在是为了递归匿名函数。
观察下面代码片断被包在serTimeout中调用:
setTimeout(function factorial(n) { return n == 1 ? n : n*factorial(n-1) }, 100)
代码的结果是什么?为何?
( function g() { return 1 } ) alert(g)
答案:
结果是error:
( function g() { return 1 } ) alert(g)
解决方案的关键是理解(function ... )是一个函数表达式(参考本章),不是函数声明。
那么,咱们有一个有名函数表达式。
有名函数表达式的名字只在内部可见。
除了IE9.0如下,全部浏览器都支持NFEs,那么他们会给出错误“undefined variable”,由于g只有在函数内部可见。
ie9.0如下不支持NFE,就会输出函数
函数命名
函数是一个动做。因此命名应该是动词,像get,read,caculateSum,等等。
短函数名称的规则:
一个函数是临时的且只使用在附近的代码。变量的短命名可用这个逻辑。
一个函数用在代码任何地方。一方米昂,没有忘记他的危险,另外一方面,你能够写的更少。
真实的例子‘$’, ‘$$’, ‘$A’, ‘$F’ 等。
JavaScript库中频繁调用的函数用这些短名称。
其余状况,函数的名字应该是一个动词,或者一个动词开头的多个词叠加。
总结
JavaScript中函数是普通值。他们能够按需求被赋值,传递,调用。
一个不返回值的函数事实上会返回一个特殊值:undefined。
使用动词命名函数。短命名容许被用在两种状况:被用在附近代码块,或被很是普遍使用。
整体来讲,推荐使用函数声明,除非有缘由须要使用函数表达式。