【问题标题】:How does the outer function "store" the arguments for the inner function? [duplicate]外部函数如何“存储”内部函数的参数? [复制]
【发布时间】:2014-02-26 08:27:46
【问题描述】:

我在 Mozilla 开发者页面中找到了这个示例,但无法理解这个概念。

   function outside(x) {
       function inside(y) {
          return x + y;
       }
       return inside;
    }
    fn_inside = outside(3); //returns inside(y) -- from firebug
    result = fn_inside(5); // returns 8

    result1 = outside(3)(5); // returns 8

似乎 3 有点存储在函数 'inside' 中,在第二次调用期间将其与 5 相加并返回 8。

与第一次调用不同,第二次调用外部(outside(3)(5))返回值(8)而不是内部函数(inside)如何?

【问题讨论】:

  • @elclanrs 也许吧。但我什至没有看到 OP 在这里有什么问题......可能是 “函数如何存储在变量中?”“变量如何工作?”。 ..

标签: javascript function


【解决方案1】:

似乎 3 有点存储在函数“内部”中,在第二次调用期间将其与 5 相加并返回 8。

没错。对outside 的每次调用都会创建一个 inside 函数,并且该函数将调用outside 的数据绑定到它。它“关闭”了这些数据。这些被称为“闭包”。不要让这个名字打扰你,closures are not complicated

与第一次调用不同,第二次调用外部(outside(3)(5))返回值(8)而不是内部函数(inside)如何?

outside 的第二次调用确实返回一个函数(该调用生成的inside 函数);但随后您会立即使用第二对 () 调用该函数。

线

outside(3)(5);

...分解如下:

var f = outside(3); // Create and get the `inside` function bound to 3
f(5);               // Call it, passing in `5`

来自您的评论:

所以你的意思是,在outside(3) 的第一次调用中,“返回”的inside 方法定义变为(更改为?)返回3 + y;。是这样吗?

关闭,但不完全。 x 的值不会被烧入insideinside 具有对创建它的上下文的引用,并且该上下文使其可以访问 x 参数。这些并不完全相同,我们可以看到如果我们稍微更新一下示例(并放弃数学,这只会使事情变得模糊):

function outside(name) {
    // 'inside' uses the 'name' argument from the call to 'outside' that created it
    function inside() {
        return name;
    }

    // 'changer' *changes* the 'name' argument's value
    function makeCaps() {
        name = name.toUpperCase();
    }

    // Return both of them
    return {
        inside: inside,
        makeCaps: makeCaps
    };
}

var funcs = outside("foo");
funcs.inside();      // "foo", because 'inside' uses the 'name' created
                     // by the call to 'outside', and that 'name' is
                     // currently "foo"
funcs.makeCaps();    // Changes that same 'name'
funcs.inside();      // "FOO", because that 'name' has been changed

了解insidechanger 都关闭在相同 上下文中很关键,这是创建它们的outside 调用的上下文。

了解每次调用 outside 都会创建新上下文和新函数也是关键:

var funcs1 = outside("foo");
var funcs2 = outside("separate");
funcs1.inside();     // "foo"
funcs2.inside();     // "separate"
funcs1.makeCaps();
funcs1.inside();     // "FOO"
funcs2.inside();     // "separate"

【讨论】:

  • 谢谢克劳德。现在有点清楚了。所以你的意思是,在outside(3) 的第一次调用中,方法定义内部的“返回”变为(更改为?)return 3 + y;。对吗?
  • @Bere:接近,但不完全;我在上面添加了进一步的解释。
  • 我差不多明白这个概念了。最后一个问题:我认为之后例如outside("foo") 被调用,它消失了,它的内存被回收......,没有它的痕迹 - 除了它返回的值。但是从您的回答中我了解到,通过保留其内部功能,我们实际上可以保留外部功能的“上下文”(变量...)。是吗?
  • 谢谢! (得到最后一个问题的答案stackoverflow.com/questions/111102/…
  • @Bere:没错。当您调用一个函数时,会创建一个上下文。当函数返回时,如果没有任何引用上下文的存在,则可以清理该上下文(垃圾收集)。但在这种情况下,因为这些函数具有对上下文的引用,并且outer 返回对这些函数的引用,所以无法清理上下文。将其视为一个对象,并且函数对象具有引用该对象的属性。 (事实上​​,这基本上就是规范的内容;我已经简化了一点,但这就是它的本质。)
【解决方案2】:

您的变量“X”在外部函数的范围内以及您的内部函数。因此,当您调用外部 func 时,它会在内部创建新函数并存储您的变量 X,然后,当执行对内部函数的调用时,您已经有了 X,只需从它的 args 中获取 Y。

【讨论】:

    猜你喜欢
    • 2016-01-13
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2021-09-21
    • 2015-11-13
    • 2012-08-25
    • 1970-01-01
    • 2018-06-12
    相关资源
    最近更新 更多