JS闭包

javascript中最为重要的两个概念:原型链、闭包。原型链在上次的文章中有分析过,这次说下闭包。 ##执行环境和作用域链 要理解闭包,我们先得了解javascript的执行环境和作用域链的概念。

执行环境定义了变量或者函数有权访问的其他数据,每个执行环境都有一个与之关联的变量对象(作用域),环境中定义的变量都存储在这个对象中。

进入一个函数时,它的执行环境会被压入到一个环境栈中,然后根据它的变量对象创建一个作用域链,顺序就是环境栈中的顺序,全局执行环境的变量对象是作用域链中的最后一个,该函数的执行环境的变量对象是最前端。等到函数执行完,销毁作用域链并将执行环境弹出环境栈。

函数中对于变量的查找就是顺着这个作用域链一级一级搜索。所以在函数内部可以读取全局变量,而在函数外部是无法读取函数内部变量 ##从外部访问函数内部变量 基于作用域链的原理,函数的变量只有自己和它的子函数能访问,如果我们将这个子函数返回给外部的一个变量,会发生什么?

	function f1() {
		var num = 1;
		return function f2() {
			console.log(num);
		}
	}
	var func = f1();
	func();

我们在控制太会看到有输出,为什么呢?f1在执行完返回f2的时候,f1的执行环境会弹出环境栈,它的作用域链也会被摧毁,但是因为返回的f2函数的作用域链有在引用f1的活动对象,所以f1的活动对象并不会摧毁,只要f2不被销毁,f2会带着f1的作用域,所以在全局环境中调用func(),也就是调用f2,能访问f1的变量num。 ##闭包的概念 上述中的子函数f2就是闭包。闭包就是定义在一个函数内部的一个函数,它将函数的内部和外部连接了起来,让在函数外部能够有权访问函数内部的变量

其实这个父函数f1很像是一个类,里面定义的变量就是它的私有属性,外部需要访问f1里的私有属性,怎么办?提供一个共有方法f2给外部调用。f2就是闭包 ##闭包的作用 使用闭包有两个好处

  • 能从函数外部访问函数内部变量
  • 保存状态
	function f1() {
		var num = 1;
		return function f2() {
			console.log(num);
			num++;
		}
	}
	var func = f1();
	func();
	func();

控制台会输出1、2。这是因为第一次调用func之后,闭包会携带包含环境f1的作用域,所以会保存num的状态(已加1),第二次调用那么就会显示2.。

##闭包的问题 闭包的这种机制会带来一些问题

  • 闭包由于会携带包含环境的作用域,因此会占用更多的内存
  • 闭包只能取得包含环境中变量的最后一个值
	function f1() {
		var result = new Array();

		for(var i = 0; i < 10; i++) {
			result[i] = function() {
				return i;
			}
		}
		return result;
	}
	for (var i = 0; i < 10; i++) {
		console.log(f1()[i]());
	}

由于闭包保存的状态i最后是10,所以上述示例会返回10个10,而不是0-9。我们需要再在外面套一层闭包来解决。

	function f1() {
		var result = new Array();

		for(var i = 0; i < 10; i++) {
			result[i] = function(num) {
				return function() {
					return num;
				}
			}(i)
		}
		return result;
	}
	for (var i = 0; i < 10; i++) {
		console.log(f1()[i]());
	}

由于闭包存在的这些问题,所以一定要谨慎使用。

转载于:https://my.oschina.net/u/3643736/blog/1524346

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值