1) 函数声明方式
functiondouble(x){return2*x;}2)Function构造函数,把参数列表和函数体都作为字符串,不方便,不建议使用
vardouble=newFunction('x','return2*x;');3)函数表达式方式
vardouble=function(x){return2*x;}该形式中,等号右边是一个匿名函数,创建函数完毕后,将该函数赋给了变量double。
1)第一种方式
var double= function(x){return2*x;}等号右边是一个匿名函数。注意匿名函数不能直接独立的房子代码中,如下代码
functino(x){return2*x;} //SyntaxError:Unexpectedtoken(2)第二种方式
(function(x,y){console.log(x+y);})(2,3);创建一个匿名函数(在第一个括号内),第二个括号用于调用该匿名函数并传入参数。
闭包的含义:外层函数包含内层函数,内层函数可以访问外层函数的所有变量,即使外层函数执行完毕。(Javascript作用域链)
题外话:上述对于闭包的解释与《JavaScript 闭包系列一》中不完全吻合。 上述解释,闭包成立只需满足:函数inner嵌套在函数outer内部。另一些文章对于闭包的解释,闭包成立需要两个条件:1)函数inner嵌套在函数outer内部;2)函数outer返回函数inner。对此,我已经凌乱了,各路大侠谁能够给个定论?
Example 1:
函数outer是瞬间执行的(约0.00001毫秒),在函数outer体内创建了一个变量str,在outer执行完毕后,str变量未被释放,这是由于setTimeout内的匿名函数存在对变量str的引用。等到2秒后,匿名函数执行完毕,str才被释放。
functionouter(){varstr="closure";setTimeout(function(){console.log(str);},2000);}outer();//closureExample 2:此例是否为闭包呢?
functionouter(){vari=22;(functioninner(){console.log(i);})();}outer();//22Example 3:简化代码
functionforTimeout(x,y){console.log(x+y);}functiondelay(x,y,time){setTimeout('forTimeout('+x+','+y+')',time);}//简化后functiondelay(x,y,time){setTimeout(function(){forTimeout(x,y);},time);}delay(3,4,2000);//7匿名函数的最大用途是创建闭包,它也可用来构建命名空间,减少全局变量的使用。
Example1:
匿名函数中的addEvent和removeEvent为局部变量,但是可以通过全局变量oEvent使用它,大大减少了全局变量的使用,增强了网页的安全性。
varoEvent={};(function(){varaddEvent=function(){};functionremoveEvent(){}oEvent.addEvent=addEvent;oEvent.removeEvent=removeEvent;})();Example2:
创建一个变量sun_mile_rain,并通过直接调用匿名函数初始化为5,这种小技巧有时十分有用。
varsun_mile_rain=(function(x,y){returnx+y;})(2,3);console.log(sun_mile_rain);//5//也可使用如下的方式,第一个括号只是帮助我们阅读,但是不推荐下面这种书写格式varsun_mile_rain=function(x,y){returnx+y;}(2,3);Example3:
代码中,变量one定义在函数内部,是一个局部变量,因此外部是不可以访问的。但inner函数可以访问变量one,又将全局变量outer引用了inner,因此执行outer()能访问到one的值。
varouter=null;(function(){varone=1;functioninner(){one+=1;console.log(one);}outer=inner;})();outer();//2outer();//3outer();//4换一种形式:函数fn执行,返回inner,将fn的执行结果赋给全局变量outer。执行outer也能访问到one的值。因此可得知闭包的形式可以有多种。
functionfn(){varone=1;functioninner(){one+=1;console.log(one);}returninner;}varouter=fn();outer();//2outer();//3outer();//4闭包允许内层函数引用父函数中的变量,但该变量是最终值。
鼠标移过每一个li元素时,控制台输出的值都是3,而不是我们期望的元素下标。当mouSEOver事件调用监听函数时,首先在匿名函数内部查找i是否定义,结果没找到,因此向上查找,在全局环境中找到i,并且i的值是3(循环后的值)。因此每次输出的都是3。
/*<ul><li>one</li><li>two</li><li>three</li></ul>*/varlists=document.getElementsByTagName("li");for(vari=0;i<lists.length;i++){lists[i].onmouseover=function(){console.log(i);}}注意:此处的闭包,并不是函数嵌套函数的形式,而是匿名函数包含在全局环境中的形式。
针对上述代码,有三种方法改进,使得鼠标移动到li元素上时,控制台输出对应的下标值。
1)立即执行的匿名函数
varlists=document.getElementsByTagName("li");for(vari=0;i<lists.length;i++){(function(index){lists[i].onmouseover=function(){console.log(index);};})(i);}2)在DOM元素上绑定$$index属性记录下标
varlists=document.getElementsByTagName("li");for(vari=0;i<lists.length;i++){lists[i].$$index=i;lists[i].onmouseover=function(){console.log(this.$$index);};}3)
varlists=document.getElementsByTagName("li");for(vari=0;i<lists.length;i++){eventListener(lists[i],i);}functioneventListener(list,index){list.onmouseover=function(){console.log(index);}}时间:2014-10-23
地点:合肥
引用:http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html
新闻热点
疑难解答