前言
Javascript闭包在学习过程中通常很难理解。 本文从闭包是什么、常见闭包示例、闭包函数、闭包应用和闭包问题等方面介绍了闭包。 希望能给大家带来更深刻的理解。 理解,如有不当之处请指出,谢谢。
1.什么是闭包?
闭包是指引用父函数范围内的数据的嵌套内部(子)函数,从而形成闭包。
1. 必须有一个嵌套函数来生成闭包。 2. 闭包是一个函数,也是一个嵌套的内部函数。 3、闭包的内部函数必须引用父函数作用域内的数据。
function person(){
var name='marshal';
function student(){ //声明子函数
console.log(name);//引用父函数作用域的变量name
}
}
person();//函数执行,产生闭包
1.2 闭合形成时机
function person(){
var name='marshal';//js执行此行时,产生闭包
function student(){ //声明子函数
console.log(name);//引用父函数作用域的变量name
}
student();//内部函数在外部函数调用
}
person();//函数执行,虽满足闭包条件,但未产生闭包
闭包形成时机:嵌套子函数代码块引用父函数作用域中的数据,在执行嵌套子函数之前创建上下文时形成闭包。 或者简单的说,当外部执行嵌套的子函数时,此时就形成了一个闭包。
function person(){
var name='marshal';
function student(){
console.log(name); //该方法代码内为闭包代码
}
return student;
}
var p=person();//因创建子函数对像,此时产生第一次闭包,并将子函数student返回给p,由于p没有消失,子函数引用的变量name,一直在内存在存储,直到将p=null,进行回收
p();//执行子函数的闭包代码块,输出"marhsal"
p();//第二次执行子函数的闭包代码块,输出"marhsal"
person();//第二次创建子函数调对象,此时产生第二次闭包,但不执行子函数student代码块
2. 常见闭包示例 2.1 子函数作为形参传递
function setTimeoutTest(message,time){
setTimeout(function(){
alert(message);//嵌套子函数引用父函数变量message,产生闭包
},time);
}
setTimeoutTest('提示信息',1000);
function count(){
var i=1;
function add(){
i++;
console.log(i);
}
return add;
}
var c=count();//生产闭包
c();//2
c();//3
c();//4
2)它的变量或函数仍然存在,并且可以从外部访问函数内部的值
function count(){
var i=1;
function add(){
i++;
console.log(i);
}
return add;
}
var c=count();
c();//2
c();//3 i的生命周期延长
外部js代码 out.js 实现自加与自减
(function count(){
var i=1;
function add(){
i++;
console.log(i);
}
function subtract(){
i--
console.log(i);
}
window.count={
add:add,
subtract:subtract
}
})();
引用 out.js代码
count.add(); //2
count.subtract();//1
count.subtract();//0
5. 关闭问题 5.1 关闭与此
var name="marshal"; //创建全局变量
var person={
name:"leo",
getName:function(){ //返回匿名函数
return function(){ //返回this.name
return this.name; //返回字符串
}
}
};
alert(person.getName()()); //输出marshal,内部函数不可能直接访问外部函数this
var name="marshal";
var person={
name:"leo",
getName:function(){
var that=this;//把this保存到闭包可以访问的另一个变量中
return function(){
return that.name;
}
}
};
alert(person.getName()());//that 指向person,而不是window
5.2 内存泄漏
使用闭包时javascript闭包作用,因变量仍然存在javascript闭包作用,需要解引用该对象并将该对象设置为null,以确保可以在适当的时候回收它。