闭包的概念
内层的函数可以引用存在于包围它的函数内的变量,即使外层函数的执行已经终止。可理解为,闭包就是能够读取其他函数内部变量的函数。
表现形式是:定义在函数内部的函数。
function f1(){ var n=999; function f2(){ alert(n); // 999 } }
如上,f2函数可以访问到f1的局部变量n
反之则不行。我们无法获得内置函数的局部变量。
function add(num1){ return function(num2){ return num1+num2; }; } var num2 = add(4);
// 9 alert(num2(5));
闭包的作用
1. 使用匿名函数来隐藏全局作用域变量
这是一个自执行函数,对于msg变量,执行完立即释放。不污染全局对象。
(function(){ var msg = "Bye"; window.onload=function(){ alert(msg); } })();
闭包的问题:闭包可以引用父函数中的变量,但提供的值并非该变量创建时的值,是在父函数范围内的最终值。最常见的问题是在for循环中
2. 绑定事件的例子
1.通过数组给对象绑定多个事件
2.obj.方法名 等价于 obj"方法名"]数组写法
(function(){ var obj = document.getElementById("main"); var items = ["click","mouseover"]; for(var i=0;i<items.length;i++){ (function(){ var item = items[i]; obj["on"+ item] = function(){ alert("you have "+item); } })() } })();
3. 结果缓存
有一个需求,每次执行变量值加1。在不使用全局变量的情况下我们可以使用闭包
function f1(){ var n = 1; plusOne = function(){ n+=1; alert(n); } return plusOne; } f1(); plusOne(); // 2 plusOne(); // 3 // n is not defined alert(n);
4. 封装, 模拟对象的私有方法
var person = function(){ //变量作用域为函数内部,外部无法访问 var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }(); print(person.name);//直接访问,结果为undefined print(person.getName()); person.setName("abruzzi"); print(person.getName());
再来个例子
var event = {}; (function(){ var add = function(){ return this.age+1; } event.add = add; })();
event.age = 1; var age = event.add(); alert(age)
// 出错
add()
上例中。add是局部方法,却可以通过全局对象event调用。防止暴露了内部方法。这样可以提高安全性。
参考:
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
http://www.2cto.com/kf/201410/342609.html