匿名函数
函数的定义
1.常规定义
1 2 3
| function double(x){ return x * x; }
|
2.使用了Function构造函数,把参数列表和函数体都作为字符串
1
| var double = new Function('x', 'return x * x;');
|
3.匿名函数赋值
1 2 3
| var double = function(x) { return x* x; }
|
匿名函数的创建
1 2 3
| (function(x, y){ alert(x + y); })(2, 3);
|
第一个括号创建了一个匿名函数,第二个括号调用该匿名函数,并传入参数。
闭包
1 2 3 4 5 6 7 8 9
| var counter = 0; function add() { counter += 1; } add(); add(); add();
|
1 2 3 4 5 6 7 8
| function add() { var counter = 0; counter += 1; } add(); add(); add();
|
所有函数都能访问全局变量。
实际上,在 JavaScript 中,所有函数都能访问它们上一层的作用域。
JavaScript 支持嵌套函数。嵌套函数可以访问上一层的函数变量。
该实例中,内嵌函数可以访问父函数的 counter 变量:
1 2 3 4 5 6 7 8
| var add = (function () { var counter = 0; return function () {return counter += 1;} })(); add(); add(); add();
|
变量 add 指定了函数自我调用的返回值。
自我调用函数只执行一次。设置计数器为 0。并返回函数表达式。
add变量可以作为一个函数使用。非常棒的部分是它可以访问函数上一层作用域的计数器。
这个叫作 JavaScript 闭包。它使得函数拥有私有变量变成可能。
计数器受匿名函数的作用域保护,只能通过 add 方法修改。
- 闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。
事件监听
1 2 3 4 5 6
| var lists = document.getElementsByTagName('li'); for(var i = 0 ; i < lists.length ; i++){ lists[ i ].onmouseover = function(){ alert(i); }; }
|
当鼠标移过每一个li元素时,总是弹出lists.length,而不是我们期待的元素下标。当mouseover事件调用监听函数时,首先在匿名函数( function(){ alert(i); })内部查找是否定义了 i,结果是没有定义;因此它会向上查找,查找结果是已经定义了,并且i的值是lists.length(循环后的i值);所以,最终每次弹出的都是lists.length。
为得到想要的结果
解决方法一:
1 2 3 4 5 6 7 8
| var lists = document.getElementsByTagName('li'); for(var i = 0 , len = lists.length ; i < len ; i++){ (function(index){ lists[ index ].onmouseover = function(){ alert(index); }; })(i); }
|
解决方法二:
1 2 3 4 5 6 7
| var lists = document.getElementsByTagName('li'); for(var i = 0, len = lists.length; i < len; i++){ lists[ i ].$$index = i; lists[ i ].onmouseover = function(){ alert(this.$$index); }; }
|
解决方法三:
1 2 3 4 5 6 7 8 9
| 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); }
|
详谈JavaScript 匿名函数及闭包
对JAVASCRIPT匿名函数的理解(透彻版)
JavaScript 闭包