函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途。匿名函数:就是 没有函数名的函数。javascript
第一种:这也是最常规的一种java
function double(x){ return 2 * x; }
第二种:这种方法使用了Function构造函数,把参数列表和函数体都做为字符串,很不方便,不建议使用。 浏览器
var double = new Function('x', 'return 2 * x;');
第三种:安全
var double = function(x) { return 2* x; }
注意“=”右边的函数就是一个匿名函数,创造完毕函数后,又将该函数赋给了变量 square。闭包
第一种方式:就是上面所讲的定义square函数,这也是最经常使用的方式之一。函数
第二种方式:优化
(function(x, y){ alert(x + y); })(2, 3);
这里建立了一个匿名函数(在第一个括号内),第二个括号用于调用该匿名函数,并传入参数。this
闭包的英文单词是closure,这是JavaScript中很是重要的一部分知识,由于使用闭包能够大大减小咱们的代码量,使咱们的代码看上去更加清晰等等,总之功能十分强大。spa
闭包的含义:闭包说白了就是函数的嵌套,内层的函数可使用外层函数的全部变量,即便外层函数已经执行完毕(这点涉及JavaScript做用域链)。code
示例一
function checkClosure(){ var str = 'rain-man'; setTimeout( function(){ alert(str); } //这是一个匿名函数 , 2000); } checkClosure();
这个例子看上去十分的简单,仔细分析下它的执行过程仍是有许多知识点的:checkClosure函数的执行是瞬间的(也许用时只是0.00001毫秒),在checkClosure的函数体内建立了一个变量str,在checkClosure执行完毕以后str并无被释放,这是由于setTimeout内的匿名函数存在这对str的引用。待到2秒后函数体内的匿名函数被执行完毕,str才被释放。
function forTimeout(x, y){ alert(x + y); } function delay(x , y , time){ setTimeout('forTimeout(' + x + ',' + y + ')' , time); } /** * 上面的delay函数十分难以阅读,也不容易编写,但若是使用闭包就可让代码更加清晰 * function delay(x , y , time){ * setTimeout( * function(){ * forTimeout(x , y) * } * , time); * } */
匿名函数最大的用途是建立闭包(这是JavaScript语言的特性之一),而且还能够构建命名空间,以减小全局变量的使用。
var oEvent = {}; (function(){ var addEvent = function(){ /*代码的实现省略了*/ }; function removeEvent(){} oEvent.addEvent = addEvent; oEvent.removeEvent = removeEvent; })();
在这段代码中函数addEvent和removeEvent都是局部变量,但咱们能够经过全局变量oEvent使用它,这就大大减小了全局变量的使用,加强了网页的安全性。 咱们要想使用此段代码:oEvent.addEvent(document.getElementById('box') , 'click' , function(){});
var rainman = (function(x , y){ return x + y; })(2 , 3); /** * 也能够写成下面的形式,由于第一个括号只是帮助咱们阅读,可是不推荐使用下面这种书写格式。 * var rainman = function(x , y){ * return x + y; * }(2 , 3); */
在这里咱们建立了一个变量rainman,并经过直接调用匿名函数初始化为5,这种小技巧有时十分实用。
var outer = null; (function(){ var one = 1; function inner (){ one += 1; alert(one); } outer = inner; })(); outer(); //2 outer(); //3 outer(); //4
这段代码中的变量one是一个局部变量(由于它被定义在一个函数以内),所以外部是不能够访问的。可是这里咱们建立了inner函数,inner函数是能够访问变量one的;又将全局变量outer引用了inner,因此三次调用outer会弹出递增的结果。
4.1 闭包容许内层函数引用父函数中的变量,可是该变量是最终值
示例六:
/** * <body> * <ul> * <li>one</li> * <li>two</li> * <li>three</li> * <li>one</li> * </ul> */ var lists = document.getElementsByTagName('li'); for(var i = 0 , len = lists.length ; i < len ; i++){ lists[ i ].onmouseover = function(){ alert(i); }; }
你会发现当鼠标移过每个<li&rt;元素时,老是弹出4,而不是咱们期待的元素下标。这是为何呢?注意事项里已经讲了(最终值)。显然这种解释过于简单,当mouseover事件调用监听函数时,首先在匿名函数( function(){ alert(i); })内部查找是否认义了 i,结果是没有定义;所以它会向上查找,查找结果是已经定义了,而且i的值是4(循环后的i值);因此,最终每次弹出的都是4。
解决方法一
var lists = document.getElementsByTagName('li'); for(var i = 0 , len = lists.length ; i < len ; i++){ (function(index){ lists[ index ].onmouseover = function(){ alert(index); }; })(i); }
解决方法二:
var lists = document.getElementsByTagName('li'); for(var i = 0, len = lists.length; i < len; i++){ lists[ i ].$$index = i; //经过在Dom元素上绑定$$index属性记录下标 lists[ i ].onmouseover = function(){ alert(this.$$index); }; }
解决方法三:
function eventListener(list, index){ list.onmouseover = function(){ alert(index); }; } var lists = document.getElementsByTagName('li'); for(var i = 0 , len = lists.length ; i < len ; i++){ eventListener(lists[ i ] , i); }
使用闭包十分容易形成浏览器的内存泄露,严重状况下会是浏览器挂死