[探讨]各位大佬,你们认为这段代码有形成闭包吗?

2018-09-05 22:45:46 +08:00
 gooqiao
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}

function setupHelp() {
var helpText = [
{'id': 'email', 'help': 'Your e-mail address'},
{'id': 'name', 'help': 'Your full name'},
{'id': 'age', 'help': 'Your age (you must be over 16)'}
];

for (var i = 0; i < helpText.length; i++) {
(function() {
var item = helpText[i];
document.getElementById(item.id).onfocus = function() {
showHelp(item.help);
}
})(); // 马上把当前循环项的 item 与事件回调相关联起来
}
}

setupHelp();


重点在自执行函数上,这个自执行函数有形成闭包吗?
先说说我的观点,我不认为这有形成闭包,而只是创建了一个新的函数作用域而已。
为什么我会这么认为,我先说说我对闭包的定义:闭包必须是越过原执行环境访问到了正常情况下不能访问的对象。很明显上述代码中并没有越过原执行环境,所以不形成闭包。

贴发出来主要是想大家一起讨论下,大家互相交流学习。欢迎大家积极表达自己的意见。
2968 次点击
所在节点    编程
6 条回复
Lax
2018-09-06 01:25:18 +08:00
那个匿名函数访问到了创建它时的环境变量 helpText。
只要具备这种访问局部变量的能力就是个闭包。不能因为是原地执行就排除在外了,把这个函数 return 到外部调用方去执行和原地执行没有任何差别。
Shy07
2018-09-06 08:50:49 +08:00
个人理解:closure 就是封闭的代码块,closure 内部可以访问所在 binding 环境,而 closure 内部环境对外是不可访问的,同时 closure 可以作为参数传递。

至于 closure 内部可以访问到正常情况访问不到的对象不过是 closure 的一个特性和使用方法而已。你见到一只会飞的鸭子,你不能在它不飞时,就说它不是鸭子了。
Shy07
2018-09-06 08:53:42 +08:00
@Shy07 立即执行函数的匿名函数部分是闭包
robinlovemaggie
2018-09-06 12:57:32 +08:00
开包我会,闭包是真 TMD 蛋疼
gooqiao
2018-09-06 14:35:42 +08:00
@Shy07
如果是这样的话,那是不是就可以认为,只要在函数内部定义的函数用到了外部函数的对象都可以被看错是闭包。
但是这个内部函数所在的执行环境本就拥有对外部函数定义的对象的访问权限,并没有什么特殊的地方。
这也是我之所以认为上面代码不形成闭包的原因。
不知大佬你怎么看?
Shy07
2018-09-06 16:23:35 +08:00
@gooqiao

例子中的代码和下面的代码应该是等效的,看到 bind 就可以视作使用了闭包,我是这么认为的

```javascript
function showHelp(help) {
document.getElementById('help').innerHTML = help;
}

function setupHelp() {
var helpText = [{
'id': 'email',
'help': 'Your e-mail address'
},
{
'id': 'name',
'help': 'Your full name'
},
{
'id': 'age',
'help': 'Your age (you must be over 16)'
}
];

for (var i = 0; i < helpText.length; i++) {
var item = helpText[i];
document.getElementById(item.id).onfocus = showHelp.bind('item', item.help);
}
}
```



另外,**我不是大佬**

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/486551

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX