笔记-函数闭包

        函数的执行依赖于变量的作用域,这个变量的作用域是在函数定义的时候决定的,而不是在函数调用的时候决定的。为了实现这个词法作用域,javaScript函数对象的内部状态不仅包含函数的代码逻辑,还必须引用当前的作用域链。函数对象可以通过作用域链关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学文献中称为“闭包”。

        理解闭包先要理解嵌套函数的词法作用域规则。举个例子

	//全局变量
	var scope = "global scope";
	function checkScope() {
		//局部变量
		var scope = "local scope";
		//在作用域内返回scope
		function _f() {return scope};
		return f();
	}

	checkScope();  //结果local scope

        分析:函数checkScope声明了一个局部变量,并定义了一个函数f(),函数f()返回了这个局部变量的值,最后将函数f()的执行结果返回。现在我们将这个函数稍微的改变下,看看返回的结果是什么?

       

	//全局变量
	var scope = "global scope";
	function checkScope() {
		//局部变量
		var scope = "local scope";
		//在作用域内返回scope
		function _f() {return scope};
		return f;
	}

	checkScope()();  //结果是什么呢

        我们再在仔细分析下这个函数,和上个函数相比,变化就是返回的结果不是内部函数f()的运行结果,而是直接返回函数f()。在定义函数的作用域外调用这个函数会发生什么情况呢?

        回想一下词法作用域的规则:JavaScript函数的执行用到的作用域链,这个作用域链是在定义函数的时候创建的。嵌套函数f()定义在这个作用链内,其中的变量scope是局部变量,不管在何时运行这个函数f(),这种绑定在执行时依然有效。因此最后一行的结果不是“global scop”,而是“local scope”。

        闭包的这种特性,强大到令我们吃惊,它们可以捕捉到局部变量,并一并保存下来,看起来像这些变量绑定到了在其中定义它们的外部函数。

        在同一个作用域链内定义两个闭包函数,这两个闭包函数共享私有变量或变量。但是要特别小心那些不希望共享的变量往往不经意间共享给 其他闭包函数。

	function constfunc(value) {
		return function() {return value}
	};

	//创建一个数组用来保存常量函数
	var func[];
	for (var i=0; i<10; i++) {
		func[i] = constfunc(i);
	};

	//数组第5个位置上的函数返回的结果为5
	func[5](); //5

        上述代码利用循环创建了很多个闭包,当些这样的函数时往往会将循环体写在闭包函数之内。来看下下面的例子:

	function constfunc() {
		//创建一个数组用来保存常量函数
		var func[];
		for (var i=0; i<10; i++) {
		func[i] = function() {return i;}
		retrun func;
	};


	//数组第5个位置上的函数返回的结果又是什么呢?
	func[5](); 

        分析下这个函数,这段代码创建了10个闭包,并将它们存储在一个数组中,这些闭包都是在同一个函数中定义的,共享变量i,当执行函数constfunc(),变量i的值是10,所有的闭包都共享这一个变量,因此数组中的函数返回的结果都是10。

        嵌套函数不会将作用域链上的私有变量复制一份,也不会对所有绑定的变量生成静态快照。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值