定义的方式:
function functionName(函数名)(arg0,arg2,arg3){
//函数体
}
var functionName=function(arg0,arg1,arg2){
//函数体
}; //注意后面的分号,不能省略,省略会导致错误
一.函数声明
1.函数声明对函数的调用与产生的结果会有很大的影响。
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 </head> 6 <body> 7 <script type="text/javascript"> 8 sayHi(); 9 function sayHi(){ 10 alert("hello word"); 11 } 12 </script> 13 </body> 14 </html>
如果删除script里面的函数声明,则不能弹出内容。函数声明无论放在function定义的函数前面还是后面都可以正确产生结果。
因为函数声明中的函数声明提升会先读取函数声明,再执行函数。但是函数声明不能省略。
二.函数表达式
(1)匿名函数(anonymous function,或拉姆达函数):function关键字后无标识符,name属性值为空字符串。在把函数当成值使用时,都可用匿名函数。
(2)类似其他表达式,函数表达式使用前需先赋值,故不存在"函数声明提升"那样的作用。
(3)ECMAScript中的无效函数语法:
(4)函数表达式
三.递归(通过函数调用自身的情况下构成的)
对于经典的求阶乘函数:
1 function factorial(num){ 2 if(num<=1){ 3 return 1; 4 } 5 else { 6 return num*arguments.callee(num-1); 7 } 8 9 var result=factorial; 10 factorial=null; 11 alert(result(5));
可以看出,里面使用的变量就是在函数定义中的参数,在声明函数是也可以看出,函数是在调用自己,即使有了一个中间变量。
但是如果在输出是将里面的result改为factorial,就会出现错误,所以result变量在递归中是必不可少的
三.闭包
1.闭包有权访问另一个函数作用域中的变量的函数(在函数体内部创建),但是匿名函数就是创建一个函数。
2.
闭包用处:
(1)闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭,在函数外部不能得到函数的局部变量,但是闭包可以。
1 var name = "The Window"; 2 var object = { 3 name : "My Object", 4 getNameFunc : function(){ 5 return function(){ 6 return this.name; 7 }; 8 } 9 }; 10 alert(object.getNameFunc()());
function里面的name是访问其外部匿名函数中的name,所以alert里面电泳函数实际上就是通过闭包获取name,再返回得到值,在进行输出。
(2)一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。(会占用更多的内存)
注意:函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量
function outerFun() { var a=0; function innerFun() { a++; alert(a); } return innerFun; //注意这里 } var obj=outerFun(); obj(); //1 obj(); //2 var obj2=outerFun(); obj2(); //1 obj2(); //2
在这段代码中,是想通过函数调用outerFun()获取a的值,innerFun()的作用域在outerFun外部,但是通过创建闭包,所以能够获取到外部的变量,如果没有闭包就会出错
3.this 对象
1 var name="The window"; 2 name:"My object"; 3 getNameFunc:function(){ 4 var that=this; 5 return function(){ 6 return that.name; 7 8 }; 9 } 10 }; 11 alert(object.getNameFunc()());
在这个例子中,将this赋值给THAT,通过that在闭包中调用。通过闭包仍然可以调用闭包外面的object,可以获取name值。
在一些情况下,语法的不同会导致结果不同。
4.IE有的版本对于垃圾收集使用了不同的对象,所以对于闭包会出现一些问题。因为闭包会保存不会被销毁,所以内存永远不会被回收。所以需要将元素变量设置为null,可以解除引用,回收内存,避免闭包占用过多的内存。
原文:http://www.cnblogs.com/zzzha/p/7739790.html