闭包是什么?

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.闭包的作用
闭包的作用就是【间接的访问一个变量】。

  1. 可以读取函数内部的变量。
  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

最后一道面试题链接

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值