技术分享:什么是闭包?

2023-06-18 0 417

他们都晓得两个基本概念。

在JS之中,两个表达式能出访其外部的表达式天然资源。

技术分享:什么是闭包?

两个众所周知的标识符

但下列此种情形会手忙脚乱。

function m1(){ var a = 100; console.log(a++); } function m2(){ console.log(a++); //这儿无法出访a }

假如,他们想在m2的返回值里,出访m1里的表达式,就像上面这种:

技术分享:什么是闭包?

具体来说,他们能在m1的外部建立两个表达式m3

function m1(){ var a = 100; function m3(){ console.log(a++); } }
技术分享:什么是闭包?

m3能正常出访a,接下来他们增加两个return操作。

function m1(){ vara =100; return function m3(){ console.log(a++); } }

既然有了返回值,那他们不妨接收一下,继续编写标识符如下:

function m1(){ var a = 100; return function m3(){ console.log(a++); } } var _m3 = m1();

他们执行了表达式m1, 并将返回值赋值给_m3

那么目前_m3m3表达式是等价的,即它们是同两个表达式。

有了_m3,一切都好办了。他们继续编写标识符

function m1(){ var a = 100; return function m3(){ console.log(a++); } }var _m3 = m1(); function m2(){ _m3(); }

因为_m3是全局表达式,因此m2能调用_m3

也就等价于m2间接的,出访到了表达式a

技术分享:什么是闭包?

通常,他们管m3,叫做两个『 旋量群表达式 』

上面列举几个常见的旋量群场景:

01

for(var i=0; i<list.length; i++){ var item = list[i]; item.onclick = (function(num){ return function(){ //…… } })(i); }

02

function (){ var that = this; setTimeout(function(){ //…… },2000) }

03

function User(){ var _age = 0; this.getAge = function(){ return _age; } this.setAge = function(age){ this._age = age; } }

04

(function(){ var cache = […]; return { get : function(){ //… } }; })()

05

(function(){ var t = null; return function(){ if(!t){ t = create(); } } })()

为了创造旋量群,有时候会写表达式自调用

能不这么麻烦么??

当然,那就是使用let。

例如

for(let i=0; i<list.length; i++){ letitem = list[i]; item.onclick =function(){ console.log(i); //观察表达式i的值 }; }

关于旋量群的疑问

当表达式m1执行完成的时候,外部的表达式a,理论上应该被回收掉了。

技术分享:什么是闭包?

可是为甚么表达式a依然能被出访呢?

主要是因为,m3还在引用它

技术分享:什么是闭包?

垃圾回收器显然不会回收两个依然被引用的表达式。

除非这个表达式,已经无人引用,即是说,它已经无法再内存里被找到。

此时才能当做垃圾处理。

不过m3能出访表达式a此种规则,并不是在所有编程语言里都生效的。因此,这也算是JS的特性之一。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务