闭包的本质就是在一个函数的内部创造另一个函数,我们可以在一个函数的内部也有权访问另一个函数内部的变量。 闭包的三个特性: 1.函数嵌套函数; 2.函数内部可以引用函数外部的参数和变量; 3.参数和变量不会被垃圾回收机制收回。 闭包的两种形式: 1.函数作为返回值
function a(){
var name='dov';
return function (){
return name;
}
}
var b=a();
console.log(b);//dov
在这段代码中,实现了在全局变量中获取到局部变量中的变量的值。
function fn(){
var num=3;
return function(){
var n=0;
console.log(++n);
console.log(++num);
}
}
var fn1=fn();
fn1();//1 4
fn1();//1 5
一般情况下,当函数fn执行完后,就应该连同它里面的变量一同被销毁,但是在上面的例子中并没有,实现了在闭包中外部函数的参数和变量 不会被垃圾回收机制收回,产生了内存消耗的问题。 定时器与闭包
for(var i=0;i<5;i++){
setTimeout(function(){console.log(i+' ')},100)
}//55555
由于js都是单线程的,所以在执行for循环的时候定时器setTimeout被安排到任务队列中排队等待执行,而在等待的过程中for循环就已经在执行。所以才会出现上面的结果,如果想让它按顺序打印出当前循环次数,那么应该按着下面的修改代码:
for(var i=0;i<5;i++){
(function(i){
setTimeout(function(){console.log(i+' ')},100)
})(i);
}
//1
//2
//3
//4
//5
2.闭包作为参数传递
闭包的好处: 1.保护函数内的变量安全,实现封装,防止变量流入其他环境发生命名冲突 2.在内存中维持一个变量,可以做缓存(但同时也是一个缺点,消耗内存) 3.匿名自执行函数可以减少内存消耗 坏处: 1.在上面好处中已经体现,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄露。 解决办法:在使用完变量后手动为他赋值为null 2.由于闭包涉及跨域访问,所以会导致性能损失 解决办法:可以通过把跨作用域变量储存在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响
闭包中的this this永远指向调用者
var name = "The Window";
var obj = {
name : "The object",
getNameFunc : function(){
return function(){
return this.name;
}
}
}
alert( obj. getNameFunc()() )//The Window
解析: 执行代码object.getNameFunc()之后,它返回了一个新的函数,注意这个函数对象跟object不是一个了,可以理解为全局函数;它不再是object的属性或者方法,此时调用者是window,因此输出是 The Window。 解决方法:
var name="The Window"
var obj = {
name : "The object",
getNameFunc : function(){
var _this = this;
return function(){
return _this.name;
}
}
}
alert(object.getNameFunc()());//The object
总结: 关于js中的this,记住谁调用,this就指向谁,要访问闭包中的this,要定义个变量缓存下来,一般使用var _this=this;
|