(function() {})() 构造如何工作以及人们为什么使用它?

发布于 2024-09-07 03:32:17 字数 157 浏览 4 评论 0原文

(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 技术交流群。

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

发布评论

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

评论(15

心碎无痕… 2024-09-14 03:32:17

随着 JavaScript 框架的日益流行,$ 符号被用于许多不同的场合。因此,为了减轻可能的冲突,您可以使用这些构造:

(function ($){
  // Your code using $ here.
})(jQuery);

具体来说,这是一个匿名函数声明,它会立即执行,并将主 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:

(function ($){
  // Your code using $ here.
})(jQuery);

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.

执手闯天涯 2024-09-14 03:32:17

这是一种用于限制变量范围的技术;这是防止变量污染全局命名空间的唯一方法。

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
})();

This is a technique used to limit variable scope; it's the only way to prevent variables from polluting the global namespace.

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
})();
心作怪 2024-09-14 03:32:17

1)它定义了一个匿名函数并立即执行它。

2) 这样做通常是为了不让不需要的代码污染全局命名空间。

3)您需要从中公开一些方法,其中声明的任何内容都将是“私有”的,例如:

MyLib = (function(){
    // other private stuff here
    return {
        init: function(){
        }
    };

})();

或者,或者:

MyLib = {};
(function({
    MyLib.foo = function(){
    }
}));

重点是,您可以通过多种方式使用它,但结果保持不变。

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:

MyLib = (function(){
    // other private stuff here
    return {
        init: function(){
        }
    };

})();

Or, alternatively:

MyLib = {};
(function({
    MyLib.foo = function(){
    }
}));

The point is, there are many ways you can use it, but the result stays the same.

北城半夏 2024-09-14 03:32:17

它只是一个立即调用的匿名函数。您可以首先创建该函数,然后调用它,您会得到相同的效果:

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

工作方式:

temp = function(){ ... };
temp();

您也可以对命名函数执行相同的操作:

function temp() { ... }
temp();

您调用 jQuery 特定的代码只是在您使用其中的 jQuery 对象。它只是一个带有参数的匿名函数,会立即调用。

您可以分两步执行相同的操作,并且可以使用您喜欢的任何参数来执行此操作:

temp = function(answer){ ... };
temp(42);

这解决的问题是它为函数中的代码创建了一个闭包。您可以在其中声明变量,而不会污染全局命名空间,从而降低了将一个脚本与另一个脚本一起使用时发生冲突的风险。

在 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:

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

works as:

temp = function(){ ... };
temp();

You can also do the same with a named function:

function temp() { ... }
temp();

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:

temp = function(answer){ ... };
temp(42);

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.

多彩岁月 2024-09-14 03:32:17

它在此处解释了您的第一个构造提供了变量的作用域。

变量的作用域是 JavaScript 中的函数级别。这与您在 C# 或 Java 等语言中可能习惯的不同,在这些语言中,变量的范围仅限于块。这意味着如果您在循环或 if 语句内声明一个变量,它将可供整个函数使用。

如果您发现自己需要在函数内显式确定变量的作用域,则可以使用匿名函数来执行此操作。您实际上可以创建一个匿名函数,然后立即执行它,并且内部的所有变量都将作用于匿名函数:

(function() {
  var myProperty = "hello world";
  alert(myProperty);
})();
alert(typeof(myProperty)); // undefined

It explains here that your first construct provides scope for variables.

Variables are scoped at the function level in javascript. This is different to what you might be used to in a language like C# or Java where the variables are scoped to the block. What this means is if you declare a variable inside a loop or an if statement, it will be available to the entire function.

If you ever find yourself needing to explicitly scope a variable inside a function you can use an anonymous function to do this. You can actually create an anonymous function and then execute it straight away and all the variables inside will be scoped to the anonymous function:

(function() {
  var myProperty = "hello world";
  alert(myProperty);
})();
alert(typeof(myProperty)); // undefined
半衬遮猫 2024-09-14 03:32:17

这样做的另一个原因是消除对您正在使用哪个框架的 $ 运算符的任何混淆。例如,要强制使用 jQuery,您可以执行以下操作:

;(function($){
   ... your jQuery code here...
})(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:

;(function($){
   ... your jQuery code here...
})(jQuery);

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.

刘备忘录 2024-09-14 03:32:17

此构造的另一个用途是“捕获”将在闭包中使用的局部变量的值。例如:

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的当前值将保存在匿名函数的堆栈帧中。

Another use for this construct is to "capture" the values of local variables that will be used in a closure. For example:

for (var i = 0; i < 3; i++) {
    $("#button"+i).click(function() {
        alert(i);
    });
}

The above code will make all three buttons pop up "3". On the other hand:

for (var i = 0; i < 3; i++) {
    (function(i) {
        $("#button"+i).click(function() {
            alert(i);
        });
    })(i);
}

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.

等风也等你 2024-09-14 03:32:17

这被视为关闭。这意味着包含的代码将在其自己的词法范围内运行。这意味着您可以定义新的变量和函数,并且它们不会与闭包外部代码中使用的命名空间发生冲突。

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 不会更改预先存在的同名变量:

  • 幻数是 0
  • 闭包内的幻数是 99
  • 幻数是仍然是 0

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.

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);

This will generate three popups, demonstrating that the i in the closure does not alter the pre-existing variable of the same name:

  • The magic number is 0
  • The magic number inside the closure is 99
  • The magic number is still 0
醉殇 2024-09-14 03:32:17

它们经常用在 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.

ι不睡觉的鱼゛ 2024-09-14 03:32:17

正如其他人所说,它们都定义了立即调用的匿名函数。我通常将 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 类被分配给 < code>MyLibrary 命名空间,因此可以访问。 incrementingIDsomePrivateStaticMethod() 无法在匿名函数作用域之外直接访问。

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:

// 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();
    }
  };
})();

In this example, the MyObject class is assigned to the MyLibrary namespace, so it is accessible. incrementingID and somePrivateStaticMethod() are not directly accessible outside of the anonymous function scope.

百善笑为先 2024-09-14 03:32:17

这基本上就是 JavaScript 代码的命名空间

例如,您可以在其中放置任何变量或函数,但从外部来看,它们不存在于该范围内。因此,当您将所有内容封装在那里时,您不必担心冲突。

末尾的()表示自调用。您还可以在那里添加一个参数,该参数将成为匿名函数的参数。我经常使用 jQuery 执行此操作,您可以看到为什么...

(function($) {

    // Now I can use $, but it won't affect any other library like Prototype
})(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...

(function($) {

    // Now I can use $, but it won't affect any other library like Prototype
})(jQuery);

Evan Trimboli covers the rest in his answer.

︶葆Ⅱㄣ 2024-09-14 03:32:17

这是一个自调用函数。有点像写作的速记

function DoSomeStuff($)
{
}

DoSomeStuff(jQuery);

It's a self-invoking function. Kind of like shorthand for writing

function DoSomeStuff($)
{
}

DoSomeStuff(jQuery);
甜扑 2024-09-14 03:32:17

上面的代码所做的是在第 1 行创建一个匿名函数,然后在第 3 行使用 0 个参数调用它。这有效地封装了该库中定义的所有函数和变量,因为所有函数只能在该匿名函数内部访问。

这是一个很好的做法,其背后的原因是避免变量和函数污染全局命名空间,这些变量和函数可能会被整个站点的其他 Javascript 片段破坏。

为了阐明如何调用该函数,请考虑一个简单的示例:

如果包含这一行 Javascript,它将自动调用而无需显式调用它:

alert('hello');

因此,采用该想法,并将其应用到此示例:

(function() {
    alert('hello')
    //anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked

最终结果类似,因为匿名函数的调用就像前面的示例一样。

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:

alert('hello');

So, take that idea, and apply it to this example:

(function() {
    alert('hello')
    //anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked

The end result is similar, because the anonymous function is invoked just like the previous example.

感悟人生的甜 2024-09-14 03:32:17

因为good代码答案已经被采用了:)我会提出观看一些John Resig视频的建议视频 1 视频 2 < /strong> (jQuery 发明者和 JavaScript 大师)。

视频中提供了一些非常好的见解和答案。

这就是我看到你的问题时碰巧正在做的事情。

Because the good code 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.

狼性发作 2024-09-14 03:32:17
function(){ // some code here }

是在javascript中定义匿名函数的方法。它们可以让您能够在另一个函数的上下文中执行一个函数(否则您可能没有这种能力)。

function(){ // some code here }

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).

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