有人能解释一下这个 JavaScript 自动执行函数吗?

发布于 2024-10-06 06:18:47 字数 140 浏览 3 评论 0原文

var foo = (function(){
  var x = 0;
  return function(){return x++;};
})()

为什么 var x = 0 表达式只运行一次是我对此最大的误解。

var foo = (function(){
  var x = 0;
  return function(){return x++;};
})()

Why the var x = 0 expression only runs once is my biggest misunderstanding about this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

昵称有卵用 2024-10-13 06:18:48

匿名函数立即被后面的 () 调用(不传入任何参数)。该函数在执行时返回另一个函数,该函数有自己的 x 变量,该变量在运行时会递增。

因此,第一次运行时,foo() 将为0,第二次运行为1,依此类推,因为x它是随着不断增加而创建的。

The anonymous function gets invoked immediately by the () that follows it (passing in no parameters). That function when executed is returning another function, which has it's own x variable that gets incremented when run.

So foo() is going to be 0 the first run, 1 the second, etc, since that x it was created with continues to increment.

不打扰别人 2024-10-13 06:18:48

实际上,在本例中,x 是分配给 foo 对象的块/闭包中的局部变量。当您调用 foo() 时,该值会递增。

查看实际情况 - http://jsfiddle.net/3X283/

Actually in this case x is a local variable within the block/closure assigned to the foo object. One that gets incremented when you call foo().

Check it out in action - http://jsfiddle.net/3X283/

落叶缤纷 2024-10-13 06:18:48

这就是所谓的 闭包 这里定义了两个函数 - 内部函数(这是闭包)和创建并返回闭包的外部。

您的代码立即调用外部函数并将结果(闭包)分配给foo

请注意,闭包内的代码不包含语句 var x = 0;,因此当您调用 foo() 时,它仅执行内部的代码闭包 (return x++;)

这里提到的 x 是在调用中实例化的。闭包的有趣之处在于,这个 x 在外部函数的调用之间是不同的 - 考虑下面的示例。 foo 和 bar 将彼此独立地递增,因为它们引用不同 xs

function makeClosure(){
  var x = 0;
  return function(){return x++;};
}

var foo = makeClosure();
var bar = makeClosure();

foo(); //returns 0
foo(); //returns 1
bar(); //returns 0
foo(); //returns 2

This is what is called a closure theere are two functions defined - the inner one (which is the closure) and the outer one which creates and returns the closure.

Your code calls the outer function immediately and assigns the result (the closure) to foo.

Note the code inside the closure does not include the statement var x = 0; thus when you call foo() it only executes the code inside the closure (return x++;)

The x referred to in here is the one instantiated in the call. What makes closures interesting is that this x is different between invocations of the outer function - consider the example below. foo and bar will increment independantly of one another because they reference different xs

function makeClosure(){
  var x = 0;
  return function(){return x++;};
}

var foo = makeClosure();
var bar = makeClosure();

foo(); //returns 0
foo(); //returns 1
bar(); //returns 0
foo(); //returns 2
深府石板幽径 2024-10-13 06:18:47

您的代码:

var foo = (function(){
  var x = 0;
  return function(){return x++;};
})()

相当于此代码:

function f(){
  var x = 0;
  return function(){return x++;};
}
var foo = f();

很容易看出,当您像这样分解它时,函数 f() 仅被调用一次。它定义了x,然后返回一个在f 的本地范围内定义的函数。这个新函数通常被称为“匿名函数”(意味着它没有名称)或“闭包”。事实上,JavaScript 中的所有函数都是“闭包”——无论它们是否被命名。术语“闭包”仅意味着该函数保留对父函数作用域中定义的变量的访问权——即使在父函数退出后也是如此。

现在,foo 包含从 f 返回的新函数(闭包)。您可以根据需要多次调用 foo() —— 每次调用时,x 都会被返回并进行后递增。由于 x 存在于闭包的父作用域中,因此它的值将在对闭包的多次调用中保持不变。

更重要的是...一旦 f() 退出,其他代码现在就无法访问 x ——这基本上意味着 x 现在是“私人数据”的关闭。很整洁吧?

Your code:

var foo = (function(){
  var x = 0;
  return function(){return x++;};
})()

is equivalent to this code:

function f(){
  var x = 0;
  return function(){return x++;};
}
var foo = f();

It's easy to see, when you break it up like this, that the function f() is only called once. It defines x, and then returns a new function that is defined inside the local scope of f. This new function is often called an "anonymous function" (meaning that it has no name) or a "closure". In truth, all functions in javascript are "closures" -- whether or not they are named. The term "closure" simply means that the function retains access to the variables that were defined in the parent function's scope -- even after the parent function has exited.

So now, foo contains the new function (the closure) that was returned from f. You can call foo() as many times as you like -- and each time you do, x will be returned and post-incremented. Since x exists in the closure's parent scope, its value will persist across multiple calls to the closure.

What's more... no other code now has access to x once f() has exited -- this basically means that x is now the "private data" of the closure. Pretty neat huh?

丢了幸福的猪 2024-10-13 06:18:47

变量 foo 被分配给自执行函数的结果,如下所示:

声明一个名为 x 的变量,初始化为 0
返回一个函数,调用该函数时,将增加x 的值。

所以此时,foo 引用了一个函数

调用它的方式是:

foo();

第一次调用它时,返回的值将是 0,然后是 12...

嗯,等一下...,不应该是123 ...?

你的方向是正确的,但在这种情况下,这的原因是因为预增量之间的差异和后增量。 (++varvar++)。不同之处在于,前增量的结果是变量增量后的值,而后增量的结果是变量之前的值 em> 增量。

此示例说明了闭包的概念,这本质上意味着内部函数可以访问其周围函数中定义的变量。

The variable foo is being assigned to the result of the self-executing function, which goes as follows:

Declares a variable named x initialized to 0.
Returns a function that, when invoked, will increment the value of x.

So at this point, foo references a function.

The way you would invoke this is:

foo();

The first time this is invoked, the value returned will be 0, then 1, 2...

Well, wait a minute..., shouldn't it be 1, 2, 3...?

You are on the right track, but the reason why in this case this isn't true is because of the difference between pre-increment and post-increment. (++var vs var++). The difference is that the result of a pre-increment is the variable's value after increment, while the result of a post-increment is the variable's value before increment.

This example illustrates the concept of closures, which essentially means that inner functions have access to the variables defined in their surrounding functions.

月亮是我掰弯的 2024-10-13 06:18:47

让我们分解一下...首先我们定义一个匿名函数:

(function() { ... })

然后立即执行它:

(function() { ... })()

执行的结果是另一个函数:

function(){return x++;}

并且当我们创建上述函数时,x=0 被闭包捕获。然后我们将这个结果函数分配给 foo:

var foo = function(){return x++;}

以及闭包捕获的 x 值。每当执行 foo 时,x 就会递增。

Let's break it down... First we define an anonymous function:

(function() { ... })

We then immediately execute it:

(function() { ... })()

The result of this execution is another function:

function(){return x++;}

And the x=0 is captured by the closure when we created the above function. We then assign this resulting function to foo:

var foo = function(){return x++;}

With the value of x captured by the closure. Whenever foo is executed, x is incremented.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文