我的一个朋友和我正在讨论什么是JS的封闭,什么不是.我们只是想确保我们真正理解它.
我们来看看这个例子吧.我们有一个计数循环,并希望在控制台上打印计数器变量延迟.因此,我们使用setTimeout和闭包来捕获计数器变量的值,以确保它不会打印值N的N倍.
错误的解决方案,无需关闭或接近任何倒闭将是:
for(var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
Run Code Online (Sandbox Code Playgroud)
这当然会打印10次i循环后的值,即10.
所以他的尝试是:
for(var i = 0; i < 10; i++) {
(function(){
var i2 = i;
setTimeout(function(){
console.log(i2);
}, 1000)
})();
}
Run Code Online (Sandbox Code Playgroud)
按预期打印0到9.
我告诉他,他并没有使用封闭捕获i,但他坚持认为他是.我证明他没有使用闭包,将for循环体放在另一个setTimeout(将他的匿名函数传递给setTimeout),再次打印10次10.如果我将他的函数存储在a中var并在循环之后执行它同样适用,也打印10次10.所以我的论点是他并没有真正捕获它的值i,使他的版本不是一个闭包.
我的尝试是:
for(var i = 0; i < …Run Code Online (Sandbox Code Playgroud) 作为ECMAScriptv5,每当控件输入代码时,enginge创建一个LexicalEnvironment(LE)和一个VariableEnvironment(VE),对于功能代码,这两个对象是完全相同的引用,它是调用NewDeclarativeEnvironment(ECMAScript v5 10.4)的结果. 3),在函数代码中声明的所有变量都存储在VariableEnvironment(ECMAScript v5 10.5)的环境记录组件中,这是闭包的基本概念.
令我困惑的是Garbage Collect如何使用这种闭包方法,假设我有以下代码:
function f1() {
var o = LargeObject.fromSize('10MB');
return function() {
// here never uses o
return 'Hello world';
}
}
var f2 = f1();
Run Code Online (Sandbox Code Playgroud)
在该行之后var f2 = f1(),我们的对象图将是:
global -> f2 -> f2's VariableEnvironment -> f1's VariableEnvironment -> o
Run Code Online (Sandbox Code Playgroud)
从我的小知识来看,如果javascript引擎使用引用计数方法进行垃圾收集,则该对象o至少有1次重新引用,并且永远不会被GCed.显然这会导致浪费内存,因为o永远不会被使用但总是存储在内存中.
有人可能会说引擎知道f2的VariableEnvironment …
JavaScript中变量的生命周期是什么,用"var"声明.我相信,这绝对不是出乎意料的.
<script>
function(){
var a;
var fun=function(){
// a is accessed and modified
}
}();
</script>
Run Code Online (Sandbox Code Playgroud)
这里JavaScript垃圾如何以及何时收集变量a?由于a是内部函数闭包的一部分,理想情况下它应该永远不会被垃圾收集,因为内部函数fun可以作为对外部上下文的引用传递.所以fun应该仍然能够a从外部上下文访问.
如果我的理解是正确的,那么垃圾收集是如何发生的,以及它如何确保有足够的内存空间,因为将所有变量保留在内存中直到程序的执行可能不成立?
只是想知道,因为闭包是一个函数,它在定义之外引用了变量/方法。每个函数都关闭程序的全局变量(基本上在每种主流语言中,无论是 javascript/python/c/c+/什么)。那么,因此,每个函数都是一个闭包?
编辑:让我再次强调,我不仅在谈论 javascript 中的闭包,而且在更一般的上下文中
我一直在阅读有关closuresJS的文章。我已经浏览过各种指南,例如https://medium.freecodecamp.org/javascript-closures-simplified-d0d23fa06ba4
我仍然有一个问题。闭包是否仅引用一阶函数(返回函数的函数)。或者,是否有任何功能closure?我真正看到的唯一区别是某些函数没有嵌套,这3个作用域链(外部函数的作用域)之一将是空的,但它仍然不存在。
我正在尝试一个非常基本的 Javascript 闭包示例,但我无法在 Chrome devtools 中将其可视化。请看截图。
我创建了一个全局变量
var p = 3;
Run Code Online (Sandbox Code Playgroud)
和一个函数
function f1() {
var q = 2;
return p+q;
}
Run Code Online (Sandbox Code Playgroud)
这个函数在p里面使用了全局变量,所以这是一个闭包,对吧?如果我的理解不正确,请指导我。
那么,如果这是一个闭包,那么为什么它不在函数作用域中显示为“闭包”呢?
我遇到过多个例子,我对于在声明一个函数后放置分号感到困惑,它在函数内部充当函数,如下例所示
var myFunction = function() {
var value = "parentValue";
function otherFunction() {
var value = "childValue";
console.log("Value is : "+value);
}
otherFunction();
}
myFunction();
Run Code Online (Sandbox Code Playgroud)
即将分号放在otherFunction()声明的末尾.如果我保持; 或不是它的工作.哪个是最好的做法?
代码是否在闭包之下?为什么?
var getContact = (function(){
var person = {name: "John Doe"};
return {aFriend: person};
})();
console.log(getContact.aFriend.name);
//outputs: John DoeRun Code Online (Sandbox Code Playgroud)
我有一个错误的理解,过滤器功能是向下的 funarg 问题的一个例子吗?我在源面板下使用 chrome 调试器,并在范围部分下注意到了这一点。

过滤器函数参数cb是闭包还是strainer闭包函数?我发现很难在网上整理有关闭包和 funarg 问题的信息。我显然不明白 funarg 问题或闭包,需要一些帮助吗?
function strainer(collection, cb) {
return collection.reduce(function inner(acc, curr) {
if (cb(curr)) {
return acc.concat(curr);
}
return acc;
}, []);
}
function even(number) {
if (number % 2 === 0) {
return true;
}
return false;
}
var collection = [1, 2, 3, 4, 5];
strainer(collection, even);
Run Code Online (Sandbox Code Playgroud)
背景:我的印象是私有变量返回到外部环境创建了闭包,但该示例看起来有所不同。
下面的 flintstones 函数示例在引号函数的范围内有闭包。(我认为这是向上的 funarg 问题)
function strainer(collection, cb) {
return collection.reduce(function inner(acc, curr) {
if (cb(curr)) {
return acc.concat(curr); …Run Code Online (Sandbox Code Playgroud)