如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?
我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。
如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?
我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。
当前回答
函数和函数的外部范围(语法环境)的参考
函数 汽车(制造商,模型,年,颜色) { 返回 { 到String() { 返回 `${ 制造商} ${ 模型} (${ 年}, ${ 颜色})` } } 组车 = 新车(‘Aston Martin’,‘V8 Vantage’,‘2012’,‘Quantum Silver’) console.log(car.toString())
事件导向的编程
在下面的例子中,所有实施细节都隐藏在即时执行的函数表达式内。 函数标记和 toString 接近私人状态和函数他们需要完成工作。 关闭已使我们能够模块化和包容我们的代码。
例子1
这个例子表明,本地变量在关闭中没有复制:关闭保持了对原始变量的参考。
左边
其他回答
在JavaScript中,关闭是令人惊叹和独特的,其中变量或论点可用于内部功能,即使外部功能已返回后,它们也会活着。
function getFullName(a, b) {
return a + b;
}
function makeFullName(fn) {
return function(firstName) {
return function(secondName) {
return fn(firstName, secondName);
}
}
}
makeFullName(getFullName)("Stack")("overflow"); // Stackoverflow
维基百科 关闭:
在计算机科学中,关闭是一种函数,以及该函数的非本地名称(自由变量)的参考环境。
技术上,在JavaScript中,每个功能都是一个关闭,它总是有在周围范围内定义的变量访问。
由于JavaScript的范围定义结构是一种功能,而不是像许多其他语言一样的代码区块,我们通常在JavaScript中关闭的意思是与已执行的周围功能中定义的非本地变量的功能。
密封经常用来创建一些隐藏的私人数据的功能(但这并不总是如此)。
var db = (function() {
// Create a hidden object, which will hold the data
// it's inaccessible from the outside.
var data = {};
// Make a function, which will provide some access to the data.
return function(key, val) {
if (val === undefined) { return data[key] } // Get
else { return data[key] = val } // Set
}
// We are calling the anonymous surrounding function,
// returning the above inner function, which is a closure.
})();
db('x') // -> undefined
db('x', 1) // Set x to 1
db('x') // -> 1
// It's impossible to access the data object itself.
// We are able to get or set individual it.
EMS
上面的例子是使用一个匿名函数,一次执行,但它不一定是. 它可以被命名(例如 mkdb)并后续执行,每次被召唤时产生一个数据库函数. 每一个所产生的函数都会有自己的隐藏的数据库对象. 另一个使用例子关闭是当我们不返回一个函数时,但包含多个函数的对象
一个关闭是内部函数在其外部函数中有变量的访问,这可能是最简单的单线解释,你可以获得关闭。
我倾向于通过好/坏的比较更好地学习,我喜欢看到工作代码跟随不工作的代码,有人可能会遇到,我把一个 jsFiddle 组合起来,它进行比较,并试图将差异推向我能找到的最简单的解释。
关闭是正确的:
console.log('CLOSURES DONE RIGHT');
var arr = [];
function createClosure(n) {
return function () {
return 'n = ' + n;
}
}
for (var index = 0; index < 10; index++) {
arr[index] = createClosure(index);
}
for (var index of arr) {
console.log(arr[index]());
}
关闭错误:
console.log('CLOSURES DONE WRONG');
function createClosureArray() {
var badArr = [];
for (var index = 0; index < 10; index++) {
badArr[index] = function () {
return 'n = ' + index;
};
}
return badArr;
}
var badArr = createClosureArray();
for (var index of badArr) {
console.log(badArr[index]());
}
在上面的代码中,路径在创建ClosureArray()函数中移动,函数现在只会返回完成的路径,这在第一眼看起来更直观。
结果
我认为值得回头迈出一步,并考虑一个更普遍的“关闭”概念 - 所谓的“加入运营商”。
在数学中,“加入”操作员是部分命令集中的一个函数,返回最小的对象,大于或等于其论点。在符号中,加入 [a,b] = d 如 d >= a 和 d >= b,但没有一个 e 如 d > e >= a 或 d > e >= b。
因此,加入给你最小的东西“大”比部分。
现在,请注意,JavaScript Scopes 是一个部分安排的结构,所以有一个敏感的概念加入,特别是,一个加入 Scopes 的最小范围比原始 Scopes 大。
因此,对变量A、B、C的关闭是最小的范围(在您的程序的细节中!)将A、B、C带入范围。