浅谈JavaScript闭包
仍记得刚来到公司的时候,老大跟我们说起原型链、闭包、MV*之类的东西,当时真的是一脸懵逼的样子啊哈哈
在公司做前端开发也差不多四个月了,每一天感觉都是很忙碌,都是忙着写业务代码或者自己在学习新东西,总感觉很多知识点在这样的状态下,匆匆忙忙就略过了,自己并没有真正理解掌握下来,还是要趁有时间还是把那些东西捡回来
先看一段JS代码:
function a(){ var num = 0; function b(){ num++; console.log(num); } return b; } var add = a(); add(); // 1 add(); // 2 add(); // 3
这段代码的特点:
·函数a里面定义了一个函数b,函数b里面的操作让变量num自加的,最后一句是return b,将函数b返回了;
·add变量是指向了函数a的(有点像C的指针),函数a里面的函数b是被外部变量add引用了,函数b就形成了一个闭包了。
那闭包一般用来干嘛呢?
·在JavaScript模拟实现块级作用域,封装私有变量,防止污染全局变量
举个栗子🌰
var foo = (function(){ var secret = "secret"; return { //特权方法 get_secret : function () { return secret; }, set_secret :function(new_secret){ secret = new_secret; } } })();
alert(secret) //undefined alert(foo.get_secret()); //secret foo.set_secret("x"); alert(foo.get_secret()); //x
JS是没有类似Java的class、private关键字来封装一个私有变量的,在JS是使用闭包机制去模拟实现的,首先在匿名函数里声明一个secret变量值也为'secret',在函数的外部呢是无法访问到的。在匿名函数里return的是setter和getter方法,foo对象指向的是匿名函数,这样就能在外部去访问一个局部变量了,但是要通过setter和getter的方法,它们也叫做特权方法
再或者呢,不设置setter的方法,只有个getter的方法,老大跟我说这样就用在游戏里能防作弊了0.0
闭包的弊端:
javascript是高级语言,拥有自动的垃圾回收机制,所需内存的分配以及无用内存的回收完全实现了自动管理。简单来说就是找出那些不再继续使用的变量,然后释放其占用的内存。
垃圾收集方式主要有:1、标记清除;2、引用计数;
常见的方式就是标记清除了,垃圾收集器会给所有贮存在内存的变量加上标记,然后它会去掉环境中的变量以及被环境中被其他变量引用的变量的标记,剩下还有标记的变量就被视为准备删除垃圾了,因为它们不会再被环境所使用到,最后,垃圾收集器完成内存清除工作。
到 2008 年为止,IE、Firefox、Opera、Chrome 和 Safari 的 JavaScript 实现使用的都是标记清除式的 垃圾收集策略(或类似的策略),只不过垃圾收集的时间间隔互有不同。
正如上面说到的,闭包是在一个函数里面函数,但是被外部的变量所引用到了,所以它是会永远贮存在内存里而不会被销毁,造成了内存泄露,所以对于闭包还是要谨慎使用
以上,是对于闭包机制的一些个人理解,如果文中出现错误,欢迎大家指正:)