Javascript关闭

时间:2011-02-22 04:51:45

标签: javascript

以下程序返回“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();

3 个答案:

答案 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中的闭包和事件系统。

2016年更新

请注意,目前:

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内围绕它关闭的函数。