小白对let在for循环里闭包的一些理解
发布于 7 年前 作者 q86002618 4690 次浏览 来自 分享

首先是我对函数闭包的简单个人理解

(function (){
	var i = 0;
	return function interFunc(){
		console.log(i);
	}
}())

首先在闭包函数里面定义了一个i变量,这个i变量被interFunc函数内部引用了,所以在interFunc函数定义的时候,interFunc函数的作用域链里面会有闭包函数里面的i变量,所以在执行了闭包函数后,形成的execution context不会被释放

let在for循环里面是怎么实现闭包的?

	var a = [];
	for(let i=0;i<10;i++){
	  a[i] = ()=>{
		  console.log(i);
	  };
}
a[6]();//6

let i相当于是在for循环里面的那个块级作用域定义了一个i变量,然后又在这个块级定义了一个函数表达式,这个函数里面引用了外层作用域里的i,所以i所在的作用域的那一次循环的execution context不会被释放,构成了闭包。 也就是说,每执行一次循环,都会形成一个新的i变量,一个新的execution context。

我不知道在块级作用域里面是否会有execution context这样的东西,但是我觉得let在for循环里面实现闭包,还是因为内部函数有对块级作用域里由let定义的变量的引用,所以执行块级作用域的内存没有被释放

为什么用var关键字在for循环里面定义变量不能实现闭包?

	var a = [];
	for(var i=0;i<10;i++){
	  a[i] = ()=>{
		  console.log(i);
	  };
}
a[6]();//10

我觉得最终还是因为,javascript没有块级作用域,所谓的块级作用域也只是针对let,对var不起作用,所以在块级作用域内用var关键字定义变量i的话,其实只是在全局作用域里面定义了一个变量i,所以块级作用域里的函数引用的不是块级作用域的i,而是全局作用域里的,相当于

	var a = [];
	var i = 0;
	for(;i<10;i++){
	  a[i] = ()=>{
		  console.log(i);
	  };
}
a[6]();//10

没有对外部作用域定义的变量引用,所以每执行完一次循环,都会释放掉块级作用域里的内存,也就不存在块级作用域的闭包了。

以上是我个人的理解,不知道对不对,希望各位前辈多多指教

6 回复

并不是非得要函数才能有作用域的呀

@kyriosli 是啊

来自酷炫的 CNodeMD

是不是简单的可以理解为:闭包解决的就是在大作用域,想拿到小作用域里面定义的变量的问题。

@MengYP 这么理解完全错误吧。。。

来自酷炫的 CNodeMD

没let的话压根就没有块级作用域的概念,而不是块级被释放掉,let是后来出的东西

回到顶部