闭包是什么? ?
发布于 5 个月前 作者 yuelau 1687 次浏览 最后一次编辑是 4 个月前 来自 问答
	//例子1: 
	var x = 1;
	function fn() {
		console.log(x)
	}
	
	//函数fn 形成闭包吗?
	//答案:
	

	//例子2:
	var x = 2;
	funciton fn() {
		return funciton (){
			console.log(x)
		}
	}

	var tempFn = fn()

	//tempFn会形成闭包
	//答案:


	//例子3:
	var x = 3;
	funciton fn() {
		var y = 1;
		return function (){
			console.log(1)
		}
	}

	var tempFn = fn()
	//tempFn形成闭包吗?
	//答案:

	//例子4:
	var x= 4;
	function fn() {
		var y = 1;
		reutrn function () {
			console.log(y)
		}
	}

	var tempFn = fn()
	//tempFn形成闭包吗?
	//答案:

闭包是什么呢?

答案: 一个月了,今天chrome控制台debug了下,发现一个比较有意思的事情(例子1-3 vs 例子4)。或许这就是答案。见截图: 360反馈意见截图16230315523666.png 360反馈意见截图162807239089109.png

13 回复

不,不,不,是

是 是 否 是 闭包就是让内部作用域访问到外部作用域变量的编译器的一个技巧吧

@hyj1991 也是一不小心就泄露内存的技巧 - -

@DevinXian 是的,主要是有些闭包会非常隐晦,之前看到阿里的洗影写的一篇《A talk on V8 garbage collection logs》,里面提到v8对闭包的几个处理:

  • Closures are created when declared, not when executed
  • In V8, once there is any closure in the context, the context will be attached to every function, even for those who don’t reference the context at all

尤其是第二点,非常有意思:

var GIANT;
function leak() {
	var HUGE = GIANT;
	function unusedClosure() {
    	HUGE.slice(1);
	}
	GIANT = {
    	willBeLeaked: new Array(1e5).join('.'),
    	notAClosure: function notAClosure() {
        	return 1;
    	}
	}
}

这个例子会因为unusedClosure的闭包引用HUGE会导致在leak函数中的所有函数都会和HUGE变量产生闭包引用,即使该函数中并未使用,比如notAClosure函数。。。

@hyj1991 前两个我搞错了。学习了

@hyj1991 为什么是这样呢?

闭包是由函数(环境)及其封闭的自由变量组成的集合体。

ES 中的每个函数都是一个闭包,但通常只有嵌套的函数才能让开发者感觉出闭包的特性而已。

所以我认为,上面所有的情况都形成了闭包。

@DevinXian 看这个In V8, once there is any closure in the context, the context will be attached to every function

一个是闭包的形式,其实更重要的是闭包的作用与运用。

前几天在简书看到一篇挺有意思的说法,

function a(){
    /*a的作用域*/
    function b(){
        /*b的作用域*/
        var _b="我是_b";
        return function c(){
             console.log(_b);
        }
    }

    var _a=b();
    _a();//打印"我是_b"
}

这样是不是一下子就理解了?

只是个语言设计层面的概念,你需要知道的只是返回函数的外层作用域全部保留就可以了。

回到顶部