(function() {})() 及其特定于jQuery的表弟 (function($) {})(jQuery)一直以Javascript代码弹出。
这些构造如何工作,它们可以解决什么问题?
实例赞赏
(function() {})() 及其特定于jQuery的表弟 (function($) {})(jQuery)一直以Javascript代码弹出。
这些构造如何工作,它们可以解决什么问题?
实例赞赏
jQuery了论据。
Answers:
随着JavaScript框架的日益普及,该$标志已在许多不同的场合使用。因此,为减轻可能的冲突,可以使用以下构造:
(function ($){
// Your code using $ here.
})(jQuery);
具体来说,这是一个匿名函数声明,该声明立即通过将主jQuery对象作为参数来执行。在该函数内部,您可以$用来引用该对象,而不必担心其他框架也处于范围内。
这是一种用于限制变量范围的技术。这是防止变量污染全局名称空间的唯一方法。
var bar = 1; // bar is now part of the global namespace
alert(bar);
(function () {
var foo = 1; // foo has function scope
alert(foo);
// code to be executed goes here
})();
1)它定义一个匿名函数并立即执行它。
2)通常这样做是为了避免用不需要的代码污染全局名称空间。
3)您需要从中公开一些方法,其中声明的任何内容都是“私有的”,例如:
MyLib = (function(){
// other private stuff here
return {
init: function(){
}
};
})();
或者,或者:
MyLib = {};
(function({
MyLib.foo = function(){
}
}));
关键是,有很多方法可以使用它,但是结果保持不变。
它只是一个立即调用的匿名函数。您可以先创建函数,然后调用它,然后得到相同的效果:
(function(){ ... })();
用作:
temp = function(){ ... };
temp();
您也可以使用命名函数执行相同的操作:
function temp() { ... }
temp();
所谓的jQuery特定代码只是在其中使用jQuery对象的意义上。它只是一个带有参数的匿名函数,将立即被调用。
您可以分两步执行相同的操作,并且可以使用任意所需的参数来执行此操作:
temp = function(answer){ ... };
temp(42);
解决的问题是它为函数中的代码创建了一个closuse。您可以在其中声明变量而不会污染全局名称空间,从而降低了将一个脚本与另一个脚本一起使用时发生冲突的风险。
在jQuery的特定情况下,可以在兼容模式下使用它,即不将名称$声明为jQuery的别名。通过将jQuery对象发送到闭包中并命名参数$,您仍然可以使用与不兼容模式相同的语法。
它解释这里是你的第一个结构变量提供空间。
变量在javascript中的功能级别范围内。这与您使用C#或Java这样的语言(其中变量的作用域仅限于块)的习惯不同。这意味着如果您在循环或if语句中声明变量,则该变量将对整个函数可用。
如果您发现自己需要在函数内部显式地定义变量的范围,则可以使用匿名函数来执行此操作。您实际上可以创建一个匿名函数,然后立即执行它,并且内部的所有变量都将被限定为匿名函数:
(function() {
var myProperty = "hello world";
alert(myProperty);
})();
alert(typeof(myProperty)); // undefined
这样做的另一个原因是,消除了$您对使用哪个框架运算符的困惑。例如,要强制使用jQuery,您可以执行以下操作:
;(function($){
... your jQuery code here...
})(jQuery);
通过传入$运算符作为参数并在jQuery上调用它,$即使加载了其他框架,该函数内的运算符也将锁定到jQuery。
此构造的另一个用途是“捕获”将在闭包中使用的局部变量的值。例如:
for (var i = 0; i < 3; i++) {
$("#button"+i).click(function() {
alert(i);
});
}
上面的代码将使所有三个按钮弹出“ 3”。另一方面:
for (var i = 0; i < 3; i++) {
(function(i) {
$("#button"+i).click(function() {
alert(i);
});
})(i);
}
这将使三个按钮按预期方式弹出“ 0”,“ 1”和“ 2”。
这样做的原因是,闭包保留对其封闭堆栈框架的引用,该框架保存其变量的当前值。如果这些变量在闭包执行之前发生更改,则闭包将仅看到最新值,而不看到创建闭包时的值。通过将闭合创建内容包装在另一个内部函数中,如上面的第二个示例中所示,变量的当前值i保存在匿名函数的堆栈框架中。
这被视为关闭。这意味着所包含的代码将在其自己的词法范围内运行。这意味着您可以定义新的变量和函数,它们不会与闭包外部代码中使用的名称空间冲突。
var i = 0;
alert("The magic number is " + i);
(function() {
var i = 99;
alert("The magic number inside the closure is " + i);
})();
alert("The magic number is still " + i);
这将生成三个弹出窗口,表明i闭包中的不会更改名称相同的预先存在的变量:
它们通常在jQuery插件中使用。如jQuery Plugins Authoring Guide中所述,在内部声明的所有变量{ }都是私有的,外部不可见,从而可以更好地进行封装。
{}不要自己在JavaScript中创建新范围。作用域由函数声明创建。
正如其他人所说,它们都定义了立即调用的匿名函数。我通常将JavaScript类声明包装在此结构中,以便为该类创建静态私有范围。然后,我可以在该范围内放置常量数据,静态方法,事件处理程序或其他任何内容,并且仅对类的实例可见:
// Declare a namespace object.
window.MyLibrary = {};
// Wrap class declaration to create a private static scope.
(function() {
var incrementingID = 0;
function somePrivateStaticMethod() {
// ...
}
// Declare the MyObject class under the MyLibrary namespace.
MyLibrary.MyObject = function() {
this.id = incrementingID++;
};
// ...MyObject's prototype declaration goes here, etc...
MyLibrary.MyObject.prototype = {
memberMethod: function() {
// Do some stuff
// Maybe call a static private method!
somePrivateStaticMethod();
}
};
})();
在此示例中,MyObject该类已分配给MyLibrary名称空间,因此可以访问。 incrementingID并且somePrivateStaticMethod()不能在匿名函数范围之外直接访问。
这基本上是为您的JavaScript代码命名空间。
例如,您可以在其中放置任何变量或函数,而从外部看,它们不在该范围内。因此,当您将所有内容封装在那里时,您不必担心冲突。
将()在年底手段自我调用。您也可以在其中添加一个参数,该参数将成为匿名函数的参数。我经常使用jQuery来执行此操作,您会明白为什么...
(function($) {
// Now I can use $, but it won't affect any other library like Prototype
})(jQuery);
上面的代码正在做的事情是在第1行创建一个匿名函数,然后在第3行使用0个参数调用它。这有效地封装了该库中定义的所有函数和变量,因为所有函数只能在该匿名函数内部访问。
这是一个好习惯,其背后的原因是避免用变量和函数污染全局名称空间,而变量和函数可能会在整个站点中被其他Javascript所破坏。
为了阐明函数的调用方式,请考虑以下简单示例:
如果您包含这行Java语言,它将自动调用而无需显式调用它:
alert('hello');
因此,请采纳该想法并将其应用于以下示例:
(function() {
alert('hello')
//anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked
最终结果是相似的,因为匿名函数的调用与前面的示例一样。
//here, the anonymous function is invoked,简单,但是我之前没看过它:)
function(){ // some code here }
是在javascript中定义匿名函数的方法。它们可以使您能够在另一个函数的上下文中执行一个函数(否则您可能没有该能力)。