以下程序返回“local”,根据教程I m reading, it is designed to demonstrate the phenomenon of
closure`
我不明白为什么在最后,为了调用父函数,它将它分配给变量“child”然后调用“child”。
为什么它只是编写parentFunction();最后?
var variable = "top-level";
function parentFunction() {
var variable = "local";
function childFunction() {
print(variable);
}
return childFunction;
}
var child = parentFunction();
child();
答案 0 :(得分:6)
parentFunction()返回另一个函数,该函数分配给var child。然后,通过调用parentFunction()调用child()来调用返回的函数。
只运行parentFunction();最后不会做任何有用的事情,因为你只会丢弃它的返回值,这是一个函数。但这可行:
parentFunction()();
看到这个小提琴:http://jsfiddle.net/USCjn/
更新:更简单的例子:
function outer() { // outer function returns a function
return function() {
alert('inner function called');
}
}
x = outer(); // what is now in x? the inner function
// this is the same as saying:
// x = function() {
// alert('inner function called');
// }
x(); // now the inner function is called
看到这个小提琴:http://jsfiddle.net/bBqPY/
JavaScript中的函数可以返回函数(可以返回函数(可以返回函数......))。如果你有一个返回另一个函数的函数,那么这意味着当你调用外部函数时,你得到的是内部函数,但它还没有被调用。你必须调用你所获得的值作为实际运行内部函数体的函数。所以:
x = f();
表示 - 运行函数f并在x中存储它返回的内容(可以是字符串,数字,对象,数组或函数)。但是这个:
x = f()();
表示 - 运行一个函数f,期望它返回一个函数并运行该返回的函数(第二个括号)并在x中存储返回的函数返回的内容。
这里的函数f是一个高阶函数,因为它返回另一个函数。函数也可以将另一个函数作为参数。一般来说,函数式编程语言最强大的思想之一就是JavaScript,特别是函数只是普通的值,比如可以返回和传递的数组或数字。
您必须首先掌握高阶函数的概念,以理解JavaScript中的闭包和事件系统。
请注意,目前:
function outer() {
return function() {
alert('inner function called');
}
}
可以写成:
let outer = () => () => alert('inner function called');
使用ES6 arrow function syntax。
答案 1 :(得分:2)
有关闭包的惊人部分是内部函数(在本例中为 childFunction )可以引用其范围之外的变量(在本例中为变量)。 parentFunction 不返回 childFunction 的结果,而是返回函数的实际引用!
这意味着当您执行以下操作时......
var child = parentFunction();
...现在,孩子引用 childFunction ,而 childFunction 仍然可以访问函数所具有的任何变量创建,即使它们不再存在。
为了让parentFunction调用childFunction,您需要更改代码,如下所示:
...从
return childFunction;
要:
return childFunction();
道格拉斯·克罗克福德(JSON的先驱,除其他外)还有一篇专门讨论closures, and scoping in javascript的文章,看看他关于javascript的其他文章是值得的。
答案 2 :(得分:1)
正在证明的一点是,返回并分配给child
的函数仍然引用 variable
内声明为的parentFunction
在被调用child()
之外宣布的那个。
在javascript中创建变量作用域的唯一方法是在函数体中。通常,在返回函数后,variable
内的parentFunction
将被丢弃。
但是因为您在parentFunction
内声明了一个在该范围内引用variable
并将其传递出parentFunction
的函数,variable
中的parentFunction
是通过新功能中的参考保留。
这可以保护variable
免受外部操纵,除非在parentFunction
内围绕它关闭的函数。