闭包是什么?
1.闭包是什么?
在JavaScript第三版程序设计中,闭包是这样定义的。
所谓的闭包就是有权访问另一个函数作用域中的变量的函数。
在JavaScript权威指南是这样说的:JavaScript函数是将要执行的代码以及执行这些代码作用域构成的一个综合体。在计算机术语里,这种代码和作用域综合称为闭包。
比如:
function test(){
var num = 10;
function closure(){
console.log(num)
}
}
test();
局部变量num+函数closure就构成了闭包;
为什么要嵌套函数呢?
因为需要提供局部变量。因此才把num放在函数中,如果没有外层函数就成了全局变量。
肯定有人说,那我听说闭包是需要返回一个函数的呀?正如下面的例子一样:
function test(){
var num = 10;
function closure(){
console.log(num)
}
return closure;
}
test();
为什么要return closure呢?
不return closure;无法使用闭包。
不过也有别的方式。
function test(){
var num = 10;
closure = function(){
console.log(num):
}
}
test();
closure();
上面这个就是再没有return的情况下,也调用了closure这个函数。
test函数中,
var num = 10;
function(){
console.log(num):
}
这个就构成了闭包。
2.闭包的作用
闭包的作用就是【间接的访问一个变量】。
- 可以读取函数内部的变量。
- 让这些变量始终保存在内存中。
3.闭包存在的问题
在IE9之前闭包会导致内存泄漏。这是由于IE9之前的版本对JScript对象和COM对象使用的是引用计数回收机制。
function assignHandler(){
var element = document.getElementById("someElement");
element.onclick = function(){
alert(element.id);
};
}
上面存在的问题就是element一直被引用这,引用次数至少为1。因此在引用计数的机制下内存是永远不能回收,因此可以手动null,代码如下:
function assignHandler(){
var element = document.getElementById("someElement"); var id = element.id;
element.onclick = function(){
alert(id);
};
element = null;
}
4.闭包的应用
1.索引值的问题
html
<ul id='ul'>
<li>0</li>
<li>1</li>
<li>2</li>
</ul>
js
var oLi = document.getElementsByTagName('li');
for(var i=0;i<oLi.length;i++){
oLi[i].onclick = function(){
alert(i);
}
}
我们无论点击哪一个li,alert的都是3。这是为何?
因为for循环已经遍历完。解决这个问题的方法很多,前面已经讲过好多种,现在我们主要用闭包解决这个问题。
第一种写法:
for(var i=0;i<oLi.length;i++){
oLi[i].onclick = clickHandle(i);
}
function clickHandle(i){
return function(){
//这里的i其实就是函数外的局部变量
alert(i);
}
}
第二种写法:
for(var i=0;i<oLi.length;i++){
(function(index){ //形参
oLi[i].onclick = function(){
console.log(index);
}
})(i) //实参
}
2.模拟私有变量
function MyObject(){
var privateVariable = 10;
function privateFunction(){
return privateVariable;
}
this.publicMethod = function(){
privateVariable++;
return privateFunction();
}
}
var obj = new MyObject();
obj.publicMethod(); //11
5.常见的闭包的面试题
var name = 'This Window';
var object = {
name: 'My Object',
getNameFun: function(){
return () => {
return this.name;
}
}
}
console.log(object.getNameFun()());//'This Window'
var object = {
name: 'My Object',
getNameFun: function(){
var that = this;
return function(){
return that.name;
}
}
}
console.log(object.getNameFun()()); //'My Object'
function fun(n,o){
console.log(o);
return {
fun:function(m){//[2]
return fun(m,n);//[1]
}
}
}
var a=fun(0);////undefined
a.fun(1); //0
a.fun(2); //0
a.fun(3); //0
var b=fun(0).fun(1).fun(2).fun(3); //undefined,0,1,2
var c=fun(0).fun(1); //undefined,0,
c.fun(2);//1
c.fun(3);//1
上一篇: Matplotlib绘制折线图
下一篇: 那个点是什么