JavaScript 函数表达式
1. 在JavaScript中定义函数的方式有两种,一种是函数声明,另一种就是函数表达式。
函数声明的方法如下:
function functionName(arg0, arg1....){ 函数体 }
首先是关键字function,然后是函数的名字,这就是函数声明。 关于函数声明有一个非常重要的特征,就是在执行代码之前会先读取函数声明,这就意味着你可以把函数声明放在调用他的语句之后。如下:
1 test(); 2 function test(){ 3 alert('Hello world!'); 4 }
这样不会出什么错误,因为执行代码之前已经读取了函数声明。
函数表达式中最常见的一种形式如下:
var functionName = function(){ 函数体 }
这种函数表达式看起来像是变量赋值语句,即创建了一匿名函数并将它赋值给了functionName。之所以说一创建了一个匿名函数,那是因为关键字function后面没有名字。
既然是表达式,那么在使用它之前必须要先赋值,以下代码将会报错:
test(); var test = function(){ alert("Hello world!"); }
函数表达式与函数声明的最大区别就是函数声明的提升,就是说函数声明可以在执行之前已经读取到了内存中。看下面的代码:
if(condition){ function demo(){ alert("Hello"); } }else{ function demo(){ alert("Ni hao!"); } }
表面看上去,当condition为true的时候使用一个demo的定义,为fale的时候使用另外一个定义,但是实际上这是一种无效的语法,在严格模式'use strict'下甚至还会报错。
因为在执行之前已经读取了函数声明,所以大多数浏览器则会第二个覆盖了第一个函数声明。但是如果用函数表达式就没有什么问题了。
2. 递归
递归函数在函数调用自身的情况下形成的,如下代码:
function factorial(num){ if(num <= 1){ return 1; }else{ returm num * factorial(num - 1); } }
这是一经典的递归阶乘函数。虽然看起来没什么问题,但是在下面代码执行的时候就会报错。
var test= factorial; factorial = null; test(4);
因为在递归函数中会再次调用factorial这个function,但是factorial已经为null了所以会报错。 所以在这种情况下推荐使用arguments.callee, 如下代码
function factorial(num){ if(num <= 1){ returm 1; }else{ return num * arguments.callee(num -1); } }
我们知道arguments,每一function中都会有这个变量,代表了每一function中的参数,例如arguments[0] 表示传过来的第一参数,arguments[1] 表示传过来的第二个参数,以此类推。而arguments.callee表示的是一个当前正在执行的函数的指针,即指向当前执行的函数,因此他可以实现递归函数。但是这种语法在严格模式'use strict'下, 这种方法会报错。不过还有一种方式,函数表达式的方式来表示递归,严格模式下也不会报错,如下
var factorial = (function fn(num){ if(num <= 1){ return 1; }else{ return num * fn(num -1); } });
3. 闭包
什么是闭包呢? 闭包是有权访问一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建一个函数并返回。如下:
function createFactory(name){ return function(object1, object 2){ var value1 = object1[name]; var value2 = object2[name]; return vale1 - value2; } }
在上面的代码中反回了一个匿名函数,在匿名函数中访问了外部函数中的变量name。 这个匿名函数被返回了,而且就在算在其他的地方调用也可以访问到name,不会报错,这是因内部函数的作用域链中包含外部函数createFactory的作用域链。什么是作用域链呢? 每一个函数执行的时候都有自己的执行环境,当执行一个函数的时候,函数就会被放到一个环境栈中,执行完之后,栈将其弹出,并把控制权交给之前的函数。当代码在一个环境中执行的时候,会创建变量对象的一个作用域链。作用域链保证了对当前执行环境的变量的有序访问。
明天继续。
posted on 2016-12-06 00:23 xiaodong135 阅读(370) 评论(0) 编辑 收藏 举报