再谈JavaScript中的闭包
一、什么是闭包
闭包就是有权访问另一个函数作用域中变量的函数,因此,闭包的本质是一个函数。当一个内部函数被保存到外部时,就会生成闭包。
二、闭包的作用
1、实现公有变量,即通过局部变量实现全局变量的效果
案例:定义一个函数,每调用 一次数字累加一次,即计数器效果
//非闭包实现 var num = 0; function count() { console.log(++num); } count(); // 1 count(); // 2 count(); // 3
//闭包实现 function count() { var num = 0; function add() { console.log(++num); } return add; } var myCount = count(); myCount(); // 1 myCount(); // 2 myCount(); // 3
2、实现缓存,即多个函数可同时操作一个局部变量
function demo() { var fruit = 'apple'; var obj = { eatFruit: function() { if (fruit != '') { console.log('eat => ' + fruit); fruit = ''; } else { console.log('empty'); } }, pushFruit: function(myFruit) { fruit = myFruit; } } return obj; } var boy = demo(); boy.eatFruit(); // eat => apple boy.eatFruit(); // empty boy.pushFruit('grape'); boy.eatFruit(); // eat => grape
3、实现封装属性私有化
也就是对象无法直接访问函数内部定义的同级变量,只能通过对象相应的方法来操作变量,仍以上一代码为例
function demo() { var fruit = 'apple'; var obj = { eatFruit: function() { if (fruit != '') { console.log('eat => ' + fruit); fruit = ''; } else { console.log('empty'); } }, pushFruit: function(myFruit) { fruit = myFruit; } } return obj; } var boy = demo(); console.log(boy.fruit); // undefined
无法通过 对象点变量名 的方式直接访问变量,只能通过对象内部封装的方法来操作变量
4、模块化开发,防止污染全局变量
var demo = '全局内demo'; var init = (function(){ var demo = 'init局部内demo'; function show() { console.log(demo); } return function() { show(); } }()); init(); // init局部内demo var test = (function(){ var demo = 'test局部内demo'; function show() { console.log(demo); } return function() { show(); } }()) test(); // test局部内demo
init和test为独立模块,执行 init 和 test 函数后只会输出内部同名变量,不会影响全局同名变量。
三、闭包的害处
闭包会导致原有作用域链不释放,造成内存泄露,过多闭包会严重影响运行速度
所谓勇者,不过是在认清生活真相之后,依然热爱生活!