让我问一个问题。它是关于JavaScript中的闭包,而不是关于它们是如何工作的。
David Flanagan在他的#4; JavaScript The Definitive Guide 6th Edition"写道:
... 从技术上讲,所有JavaScript函数都是闭包:它们是对象,并且它们具有与之关联的作用域链。 ...
这是对的吗?我可以调用每个函数(函数对象+它的范围)a"关闭"?
并堆叠'标签"关闭"表示:
闭包是一个第一类函数,它引用(关闭)变量来自定义它的作用域。 如果闭包仍然存在在其定义范围结束后,它关闭的变量也将继续存在。
在JavaScript中,每个函数都引用来自定义范围的变量。所以,它仍然有效。
问题是: 为什么许多开发者会这样想?这个理论有问题吗?它不能用作一般定义吗?
答案 0 :(得分:2)
从技术上讲,所有功能都是闭包。但是如果函数没有引用任何自由变量,则闭包的环境是空的。只有当需要与函数代码一起保存的闭合变量时,函数和闭包之间的区别才有意义。因此,将不能访问任何自由变量的函数称为函数,以及那些作为闭包的函数,这是很常见的,这样您就知道了这种区别。
答案 1 :(得分:1)
这是一个棘手的术语。简单地声明的功能只是一个功能。什么使闭包是调用函数。通过调用一个函数,可以为传递的参数和声明的局部变量分配空间。
如果一个函数只是返回一些值,并且该值只是简单的东西(比如,什么都没有,或者只是一个数字或一个字符串),那么关闭就会消失,对它来说真的没什么好玩的。但是,如果某些引用参数或局部变量(大多数都是相同的)"转义"函数,然后是闭包 - 为局部变量分配的空间,以及父空间链 - 坚持下去。
这是一些参考文献可以“逃避”的方式。来自一个功能:
function escape(x, y) {
return {
x: x,
y: y,
sum: function() { return x + y; }
};
}
var foo = escape(10, 20);
alert(foo.sum()); // 30
该对象从函数返回并保存在" foo"将保持对这两个参数的引用。这是一个更有趣的例子:
function counter(start, increment) {
var current = start;
return function() {
var returnValue = current;
current += increment;
return returnValue;
};
}
var evenNumbers = counter(0, 2);
alert(evenNumbers()); // 0
alert(evenNumbers()); // 2
alert(evenNumbers()); // 4
在那一个中,返回的值本身就是一个函数。该函数涉及引用参数" increment"和一个局部变量,"当前"。
我会考虑将闭包的概念与作为第一类对象的函数概念混为一谈。这两件事确实是分开的,尽管它们具有协同作用。
作为一个警告,我不是一个基本人格的形式主义者,而且我对术语非常糟糕,所以这可能应该用downvotes来淋浴。
答案 2 :(得分:1)
我会尝试回答你的问题,因为你知道在面试过程中有什么关闭(从上面的评论中读到)。
首先,我认为你应该更加具体了解"否则"。究竟是怎么回事?
可能我们可以说一下这个noop功能的关闭:
function() {}
但似乎没有任何意义,因为没有变量会限制它的范围。
我认为即使这个例子也不太好考虑:
function closureDemo() {
var localVar = true;
}
closureDemo();
由于它的变量将被释放,因为在此函数调用之后无法访问它,因此JavaScript之间没有区别,让我们说C语言。
再一次,既然你说你已经询问了访问中关闭的内容,我想你可以通过你在closureDemo()
之后获得的外部函数来访问一些局部变量的例子会更好一些。先打个电话。像
function closureDemo() {
var localVar = true;
window.externalFunc = function() {
localVar = !localVar; // this local variable is still alive
console.log(localVar); // despite function has been already run,
// that is it was closed over the scope
}
}
closureDemo();
externalFunc();
externalFunc();
然后评论其他案例,然后得出最常见的定义,因为它更有可能让面试官同意你,而不是引用Flanagan并立即尝试找到你已经读过的页面更好地证明你的陈述或某事。 可能你的面试官只是认为你实际上并不知道闭包是什么,只是从书中读出定义。无论如何,祝你下次好运。
答案 3 :(得分:0)
定义是正确的。 封闭保持了它诞生的范围
考虑这个简单的代码:
getLabelPrinter = function( label) {
var labelPrinter = function( value) {
document.write(label+": "+value);
}
return labelPrinter; // this returns a function
}
priceLabelPrinter = getLabelPrinter('The price is');
quantityLabelPrinter = getLabelPrinter('The quantity is');
priceLabelPrinter(100);
quantityLabelPrinter(200);
//output:
//The price is: 100 The quantity is: 200