(function() {})() 构造如何工作以及人们为什么使用它?
(function() {})()
及其特定于 jQuery 的表兄弟 (function($) {})(jQuery)
始终在 Javascript 代码中弹出。
这些结构如何运作,它们解决了什么问题?
赞赏的例子
(function() {})()
and its jQuery-specific cousin (function($) {})(jQuery)
pop up all the time in Javascript code.
How do these constructs work, and what problems do they solve?
Examples appreciated
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
随着 JavaScript 框架的日益流行,
$
符号被用于许多不同的场合。因此,为了减轻可能的冲突,您可以使用这些构造:具体来说,这是一个匿名函数声明,它会立即执行,并将主 jQuery 对象作为参数传递。在该函数内,您可以使用
$
来引用该对象,而不必担心其他框架也在范围内。With the increasing popularity of JavaScript frameworks, the
$
sign was used in many different occasions. So, to alleviate possible clashes, you can use those constructs:Specifically, that's an anonymous function declaration which gets executed immediately passing the main jQuery object as parameter. Inside that function, you can use
$
to refer to that object, without worrying about other frameworks being in scope as well.这是一种用于限制变量范围的技术;这是防止变量污染全局命名空间的唯一方法。
This is a technique used to limit variable scope; it's the only way to prevent variables from polluting the global namespace.
1)它定义了一个匿名函数并立即执行它。
2)这样做通常是为了不让不需要的代码污染全局命名空间。
3)您需要从中公开一些方法,其中声明的任何内容都将是“私有”的,例如:
或者,或者:
重点是,您可以通过多种方式使用它,但结果保持不变。
1) It defines an anonymous function and executes it straight away.
2) It's usually done so as not to pollute the global namespace with unwanted code.
3) You need to expose some methods from it, anything declared inside will be "private", for example:
Or, alternatively:
The point is, there are many ways you can use it, but the result stays the same.
它只是一个立即调用的匿名函数。您可以首先创建该函数,然后调用它,您会得到相同的效果:
工作方式:
您也可以对命名函数执行相同的操作:
您调用 jQuery 特定的代码只是在您使用其中的 jQuery 对象。它只是一个带有参数的匿名函数,会立即调用。
您可以分两步执行相同的操作,并且可以使用您喜欢的任何参数来执行此操作:
这解决的问题是它为函数中的代码创建了一个闭包。您可以在其中声明变量,而不会污染全局命名空间,从而降低了将一个脚本与另一个脚本一起使用时发生冲突的风险。
在 jQuery 的特定情况下,您可以在兼容模式下使用它,其中它不会将名称 $ 声明为 jQuery 的别名。通过将 jQuery 对象发送到闭包中并命名参数 $,您仍然可以使用与没有兼容模式时相同的语法。
It's just an anonymous function that is called immediately. You could first create the function and then call it, and you get the same effect:
works as:
You can also do the same with a named function:
The code that you call jQuery-specific is only that in the sense that you use the jQuery object in it. It's just an anonymous function with a parameter, that is called immediately.
You can do the same thing in two steps, and you can do it with any parameters you like:
The problem that this solves is that it creates a closuse for the code in the function. You can declare variables in it without polluting the global namespace, thus reducing the risk of conflicts when using one script along with another.
In the specific case for jQuery you use it in compatibility mode where it doesn't declare the name $ as an alias for jQuery. By sending in the jQuery object into the closure and naming the parameter $ you can still use the same syntax as without compatibility mode.
它在此处解释了您的第一个构造提供了变量的作用域。
It explains here that your first construct provides scope for variables.
这样做的另一个原因是为了消除对您正在使用哪个框架的
$
运算符的任何混淆。例如,要强制使用 jQuery,您可以执行以下操作:通过传入
$
运算符作为参数并在 jQuery 上调用它,函数中的$
运算符将被锁定到 jQuery即使您加载了其他框架。Another reason to do this is to remove any confusion over which framework's
$
operator you are using. To force jQuery, for instance, you can do:By passing in the
$
operator as a parameter and invoking it on jQuery, the$
operator within the function is locked to jQuery even if you have other frameworks loaded.此构造的另一个用途是“捕获”将在闭包中使用的局部变量的值。例如:
上面的代码将使所有三个按钮都弹出“3”。另一方面:
这将使三个按钮按预期弹出“0”、“1”和“2”。
原因是闭包保留对其封闭堆栈框架的引用,该堆栈框架保存其变量的当前值。如果这些变量在闭包执行之前发生更改,则闭包将仅看到最新的值,而不是创建闭包时的值。通过将闭包创建包装在另一个函数内(如上面第二个示例所示),变量
i
的当前值将保存在匿名函数的堆栈帧中。Another use for this construct is to "capture" the values of local variables that will be used in a closure. For example:
The above code will make all three buttons pop up "3". On the other hand:
This will make the three buttons pop up "0", "1", and "2" as expected.
The reason for this is that a closure keeps a reference to its enclosing stack frame, which holds the current values of its variables. If those variables change before the closure executes, then the closure will see only the latest values, not the values as they were at the time the closure was created. By wrapping the closure creation inside another function as in the second example above, the current value of the variable
i
is saved in the stack frame of the anonymous function.这被视为关闭。这意味着包含的代码将在其自己的词法范围内运行。这意味着您可以定义新的变量和函数,并且它们不会与闭包外部代码中使用的命名空间发生冲突。
这将生成三个弹出窗口,证明闭包中的
i
不会更改预先存在的同名变量:This is considered a closure. It means the code contained will run within its own lexical scope. This means you can define new variables and functions and they won't collide with the namespace used in code outside of the closure.
This will generate three popups, demonstrating that the
i
in the closure does not alter the pre-existing variable of the same name:它们经常用在 jQuery 插件中。正如 jQuery 插件创作指南中所解释的,在
{ }
是私有的并且对外部不可见,这允许更好的封装。They are often used in jQuery plugins. As explained in the jQuery Plugins Authoring Guide all variables declared inside
{ }
are private and are not visible to the outside which allows for better encapsulation.正如其他人所说,它们都定义了立即调用的匿名函数。我通常将 JavaScript 类声明包装在该结构中,以便为该类创建静态私有作用域。然后,我可以在该范围内放置常量数据、静态方法、事件处理程序或任何其他内容,并且它仅对该类的实例可见:
在此示例中,
MyObject
类被分配给 < code>MyLibrary 命名空间,因此可以访问。incrementingID
和somePrivateStaticMethod()
无法在匿名函数作用域之外直接访问。As others have said, they both define anonymous functions that are invoked immediately. I generally wrap my JavaScript class declarations in this structure in order to create a static private scope for the class. I can then place constant data, static methods, event handlers, or anything else in that scope and it will only be visible to instances of the class:
In this example, the
MyObject
class is assigned to theMyLibrary
namespace, so it is accessible.incrementingID
andsomePrivateStaticMethod()
are not directly accessible outside of the anonymous function scope.这基本上就是 JavaScript 代码的命名空间。
例如,您可以在其中放置任何变量或函数,但从外部来看,它们不存在于该范围内。因此,当您将所有内容封装在那里时,您不必担心冲突。
末尾的
()
表示自调用。您还可以在那里添加一个参数,该参数将成为匿名函数的参数。我经常使用 jQuery 执行此操作,您可以看到为什么...Evan Trimboli 在他的 答案。
That is basically to namespace your JavaScript code.
For example, you can place any variables or functions within there, and from the outside, they don't exist in that scope. So when you encapsulate everything in there, you don't have to worry about clashes.
The
()
at the end means to self invoke. You can also add an argument there that will become the argument of your anonymous function. I do this with jQuery often, and you can see why...Evan Trimboli covers the rest in his answer.
这是一个自调用函数。有点像写作的速记
It's a self-invoking function. Kind of like shorthand for writing
上面的代码所做的是在第 1 行创建一个匿名函数,然后在第 3 行使用 0 个参数调用它。这有效地封装了该库中定义的所有函数和变量,因为所有函数只能在该匿名函数内部访问。
这是一个很好的做法,其背后的原因是避免变量和函数污染全局命名空间,这些变量和函数可能会被整个站点的其他 Javascript 片段破坏。
为了阐明如何调用该函数,请考虑一个简单的示例:
如果包含这一行 Javascript,它将自动调用而无需显式调用它:
因此,采用该想法,并将其应用到此示例:
最终结果类似,因为匿名函数的调用就像前面的示例一样。
What the above code is doing is creating an anonymous function on line 1, and then calling it on line 3 with 0 arguments. This effectively encapsulates all functions and variables defined within that library, because all of the functions will be accessible only inside that anonymous function.
This is good practice, and the reasoning behind it is to avoid polluting the global namespace with variables and functions, which could be clobbered by other pieces of Javascript throughout the site.
To clarify how the function is called, consider the simple example:
If you have this single line of Javascript included, it will invoke automatically without explicitly calling it:
So, take that idea, and apply it to this example:
The end result is similar, because the anonymous function is invoked just like the previous example.
因为
good代码答案已经被采用了:)我会提出观看一些John Resig视频的建议视频 1 ,视频 2 < /strong> (jQuery 发明者和 JavaScript 大师)。视频中提供了一些非常好的见解和答案。
这就是我看到你的问题时碰巧正在做的事情。
Because the
goodcode answers are already taken :) I'll throw in a suggestion to watch some John Resig videos video 1 , video 2 (inventor of jQuery & master at JavaScript).Some really good insights and answers provided in the videos.
That is what I happened to be doing at the moment when I saw your question.
是在javascript中定义匿名函数的方法。它们可以让您能够在另一个函数的上下文中执行一个函数(否则您可能没有这种能力)。
is the way to define an anonymous function in javascript. They can give you the ability to execute a function in the context of another function (where you might not have that ability otherwise).