【问题标题】:Why do I encapsulate a jQuery function within jQuery(function ($) { });为什么我在 jQuery(function ($) { }); 中封装了一个 jQuery 函数
【发布时间】:2012-06-16 12:49:51
【问题描述】:

我遇到了一段代码,如下所示:

jQuery(function($) {
  $('#saySomething').click(function() {
    alert('something');
  });
});

我不太明白。为什么我不能简单地这样做:

$('#saySomething').click(function() {
   alert('saySomething');
});

【问题讨论】:

  • 第二段代码在语法上不正确。它有一个额外的});。可能是代码遗漏了什么,或者错误本身就是问题所在?
  • 嘿,我的错误。我做了一个快速的复制和粘贴。进行了更正。
  • 没有汗水,它只是改变了解决问题的方式而已。现在我将对某人的猜测进行投票(回复:答案)。

标签: javascript jquery


【解决方案1】:
jQuery(function ($) {...});

是以下的简写形式:

jQuery(document).ready(function ($) {...});

如果您不等待 document 准备好,您要绑定事件的元素将不会存在于 dom 中,并且这些事件实际上不会被绑定。

或者,您可以等待body 完成加载,但这将包括等待图像,这需要更长的时间来加载。

说实话,you don't have to wait for document.ready。如果您知道该元素存在于 DOM 中,您可以继续使用 $('#saySomething').click(...)

<button id="saySomething>Say Something!</button>
<script>
    jQuery('#saySomething').click(...);
</script>

您应该了解jQuery(function ($) {...}); 的最后一个细微差别。函数中的$ 参数用于将jQuery 别名为$,这将允许您在函数内使用$ 简写,而不必担心与其他库(例如原型)发生冲突。

如果您不等待document.ready,通常会看到IIFE 用于别名 jQuery:

(function ($) {
    $('#saySomething').click(...);
}(jQuery));

【讨论】:

    【解决方案2】:
    jQuery(function($) {
    

    的快捷方式
    jQuery(document).ready(function(){
    

    这会等到文档处于构建 DOM 的“就绪”状态。然后,您的 jQuery 脚本可以处理整个页面,并且不会遗漏任何元素。

    但是 - 你可以在没有它的情况下运行 jQuery。如果您的脚本在头脑中,则您冒着选择尚未创建的元素的风险。我已经在我的文档正文中立即我想要影响的元素中使用了 jQuery,以便尽快对它们进行操作。这是一个不寻常的案例,我通常不会这样做。

    使用 ready 函数的另一个原因 - 您可以多次运行它。如果包含多个脚本或有条件包含的代码,则可以有多个 ready() 函数。每个就绪块中的代码会一直保持,直到达到就绪状态,然后代码按照添加的顺序执行。

    【讨论】:

    • 不是在ready块里面放多个函数,可以在jQuery(function($) {里面放多个函数吗
    • @johnywhy - 它应该做同样的事情,所以去吧。
    • 不错!这是一个很好的捷径,可以放在整个脚本周围,以简化每个单独操作的语法。正确的?为什么不是每个人都这样做?
    • 与什么相反,将单个函数(或函数集)放在单独的就绪块中?如果您在 .js 文件中有预先制作的功能块,则可以为方便起见。您可以根据需要将各个部分包含到页面中,而不必拥有所有部分。一般来说,我更喜欢将所有代码放在一个地方。一起查看脚本更容易。
    【解决方案3】:

    第一个示例在页面完全加载后执行。第二个示例直接执行(可能会失败)。

    所以,第一个是以下的简写:

    $(document).ready(function(){
      // Do something after the page is loaded.
    });
    

    【讨论】:

      【解决方案4】:

      这是“文档加载”的简写,他们还使用了带有 $ 别名的简写“jQuery”,以避免使用 $ 符号与其他库发生冲突。

      如果您不等待文档加载,事情可能会变得不可预测/无法正常工作。此外,如果您有命名冲突,事情就会彻底爆发。

      【讨论】:

        【解决方案5】:

        $(function() {}) 是 jQuerys 文档就绪功能的缩写 http://api.jquery.com/jQuery/#jQuery3http://api.jquery.com/ready/ 了解更多信息

        【讨论】:

          【解决方案6】:

          jQuery(function($) { ... }); 是在 DOM (HTML) 完全呈现并可访问之前阻止您的代码执行的原因。

          【讨论】:

            【解决方案7】:

            直接从docs复制粘贴:

            jQuery( callback ) 返回:jQuery

            描述:绑定一个在 DOM 完成时执行的函数 正在加载。

            version added: 1.0jQuery( callback )
            
            `callback` The function to execute when the DOM is ready.
            

            这个函数的行为就像$(document).ready(),因为它应该 用于包装页面上的其他 $() 操作,这些操作依赖于 DOM 准备就绪。虽然此功能在技术上是可链接的,但 对它进行链接真的没有多大用处。

            请检查 api

            【讨论】:

              【解决方案8】:

              jQuery(function(){...}jQuery(document).ready(function(){...}) 的快捷方式。 Ready 事件在 DOM 准备就绪时触发,因此您可以确定您没有访问尚未可用的内容。

              另一方面,如果您像在第二个 sn-p 上那样绑定 click 方法。该代码将立即执行,因此您需要确保将其放在#saySomething 声明之后。

              【讨论】:

                【解决方案9】:

                这将取决于代码的上下文,但 JavaScript 中有一个常见的设计实践是在命名空间或模块模式中封装变量和方法。 此代码可能是该意图的派生词。

                模块设计模式背后的原因归结为全局变量的复杂性和“破坏”的危险。

                当任何同名的变量(或函数)被定义两次时,就会发生破坏。第二个定义将覆盖第一个,实质上是破坏它。

                因此,将代码包装在一个结构中是一个经验法则,该结构将变量(和函数)与全局命名空间隔离开来。 Douglas Crockford 很好地描述了这类场景。

                这个example 显示了一个稍微更常见的化身,称为“闭包”:

                var jspy = (function() {
                    var _count = 0;
                
                    return {
                      incrementCount: function() {
                        _count++;
                      },
                      getCount: function() {
                        return _count;
                      }
                    };
                })();
                

                一开始会让人迷失方向,但一旦你意识到它,它就会变成第二天性。关键是将 _count 变量封装为返回对象的私有成员,该对象有两个可访问的方法。

                这很强大,因为全局命名空间现在只包含一个 var (jspy),而不是一个包含两个方法的变量。它强大的第二个原因是它保证了_count变量只能被两个方法(incrementCount,getCount)中的逻辑访问。

                正如我所说,您的代码可能就是这个经验法则的化身。

                无论哪种方式,了解 JavaScript 中的这种模式都很重要,因为它为框架之间更强大的交互打开了大门,例如在 AMD 中异步加载它们。

                这是一个很好的 namespace 示例。

                总而言之,有一种高级的 JavaScript 设计模式可以帮助你了解,相关术语是模块模式、命名空间模式。其他相关术语是关闭和 AMD。

                希望对您有所帮助。 一切顺利! 纳什

                【讨论】:

                • 我同意每个人的观点,这就是 document.ready。只是想提供更高级别的包装描述,如果它与上下文相关。
                • 感谢您的解释:)
                【解决方案10】:

                如果您的 jquery 不需要完全加载 DOM,您可以安全地使用任何一种形式。 为确保在执行 jquery 之前 DOM 已完全加载,请将 jquery 语句包装在 $(function... 中。

                $(function(){ ...});$(document).ready(function(){ ... }); 的快捷方式 https://stackoverflow.com/a/6454695/209942 http://jqfundamentals.com/chapter/jquery-basics

                包裹在$(function 中的Jquery 代码在所有HTML 完全解析到内存并且文档准备好与之交互之前不会被执行。

                如果在您的环境中,DOM 不能保证在渲染器命中您的 jquery 之前完全加载,那么您必须将 jquery 包装在 $(function 中。

                您也可以尝试这种替代的 DOM-ready 形式,它使 $ 成为局部变量,以避免与可能使用 $ 符号的其他变量发生冲突:

                jQuery(函数($){...}); https://stackoverflow.com/a/6454701/209942

                如果 jquery 代码没有包含在 $(function 中,它会起作用吗?如果您的 DOM 已加载,则可以。 DOM 加载取决于您加载 javascript 的方式。
                How to call a JavaScript function when the external JavaScript file is referenced at the end of the HTML body?

                请注意,这个其他类似的表单不会等待 DOM 呈现。这是一个立即执行的函数字面量。它没有前导 $ 或前导 jquery,但有尾随 open+close 括号:

                (函数(){...})();

                【讨论】:

                  猜你喜欢
                  • 2010-09-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-02-10
                  相关资源
                  最近更新 更多