$(document).ready里面放IIFE还是IIFE里面放$(document).ready?

7

我的同事在他的代码中广泛使用 (document).ready 中的 IIFE。现在,我已经阅读了这篇文章:

JQuery 最佳实践,使用 $(document).ready 在 IIFE内部?

这让我想知道我们是否应该在 IIFE 内部使用 $(document).ready,或者像我的同事一样也可以用另一种方式。

所以基本上,他的代码设置如下:

jQuery(function() {
    (function($) {
        //...
        // Code here
        //...
    })(jQuery);
});

他正在做的事情通常还好吗?

1
如果他只是想将本地$的范围隔离开来,以避免与其他库发生冲突,可以在外部函数中添加 $ 参数来实现,或者按照您建议的那样,在IIFE中包装准备好的函数。 - charlietfl
2个回答

9
有人可能会认为这是一种风格/观点问题,但是如果您考虑到 IIFE 的典型目标,我相信答案是“是的,使用您的替代方式是可以接受的,但存在潜在缺陷”。
维基百科Wikipedia指出:
立即调用的函数表达式可用于避免从块内部进行变量提升,防止污染全局环境并同时允许公共访问方法,同时保留函数内定义的变量的隐私。
两种方法都不会污染全局命名空间,因为它们不声明任何变量。因此,可以使用任何一种方法。尽管请注意,它是“部分”冗余的,因为 ready 事件的函数处理程序已经创建了一个新的作用域,并且还请注意,最常见的做法是看到 IIFE 函数将文件中的所有代码封装起来。
你的同事使用方式存在一个缺点:如果你想进行一些不依赖于DOM准备就绪的JavaScript逻辑,那么如果将代码放在IIFE之外,你将无法获得IIFE的好处。因此,像这样的内容是不安全的:
// Non-DOM-ready-required code here (NOT scope-safe)
jQuery(function() {
    (function($) {
        //...
        // DOM-ready-required code here
        //...
    })(jQuery);
});

使用通用样式可以使您获得完整的IIFE效益:
(function($) {
    // Non-DOM-ready-required code here (scope-safe)
    $(function() {
      //...
      // DOM-ready-required code here
      //...
    });
 })(jQuery);

缺点是一般问题的一个例子,即“样式”没有太多意义。任何IIFE的好处都不相关,因为代码已经在函数中运行,当文档准备就绪时运行一个函数,而不是两个函数,第一个函数已经提供了所有IIFE的优势。它可以工作,但没有任何好处。 - nomve
@nomve 你说得对。我之所以只说“部分冗余”,是因为提问者的同事可能出于其他原因这样做(重置this的值,获取安全作用域版本的 $ 等)。 - Chris Foster
我从问题和你的回答中理解到,它总是这样做的。作为一个特殊情况可以接受,但一般情况下我同意你已经说过的 - 在更典型的情况下,它会引起更多的问题。 - nomve
1
非常感谢你。经过一些痛苦的日子,这个答案确实帮了我很多。 - Adolfo F. Ibarra Landeo
@AdolfoF.IbarraLandeo 谢谢您让我知道,我很高兴它有用! - Chris Foster

1
在我看来,你的同事多此一举地添加了一个步骤。我会忽略外部的 $(document).ready,因为它实际上并没有什么影响。
/*jQuery(*/function() {
    (function($) {
        //...
        // Code here
        //...
    })(jQuery);
}/*);*/

将IIFE用作jQuery回调函数的整个主体不会在范围隔离方面提供任何额外的好处。这与代码如下情况相同:

/*jQuery(*/function() {

        //...
        // Code here
        //...

});

IIFE所做的唯一事情就是让您将jQuery引用为$

现在,如果回调函数中有更多实质性的代码,则使用内部IIFE可能会有一些好处。在下面的示例中,回调包含两个IIFE:

jQuery(function() {
    // IIFE
    (function($) {
        //...
        // Code here
        //...
    })(jQuery);
    // IIFE 2
    (function($) {
        //...
        // Code here
        //...
    })(jQuery);
});

使用IIFE可以在两个代码块之间实现作用域隔离。

回到主要问题:

这让我想到我们是否应该在IIFE内部使用$(document).ready,或者像我的同事一样使用其他方式。

说实话,即使查看了您的link,我仍然不明白为什么这些做法应该被视为最佳实践。回答问题的人从未解释过为什么它应该成为最佳实践。

看一下

(function($) {     
 $(document).ready(function() {   
    // other code here  
  });    
})(jQuery);

对抗
//(function($) {     
 $(document).ready(function() {   
    // other code here  
  });    
//})(jQuery); 

实际上,没有任何显著的优势。就像我之前的例子一样,使用IIFE并不提供作用域隔离的优势,除了允许您通过$引用jQuery外,什么也没做。

然而,在实际链接的问题中,代码看起来像这样:

(function($) {    
   // other code here 1
 $(document).ready(function() {   
    // other code here 2 
  });    
})(jQuery);

在这种情况下,IIFE确实有一个作用,即防止other code here 1中使用的变量泄漏到全局范围。但这与$(document).ready()完全无关。重构代码如下:
(function($) {    
   // other code here 1   
})(jQuery);

jQuery(document).ready(function() {   
   // other code here 2 
}); 

这个答案的寓意是,使用立即执行函数(IIFE)来包裹未在函数内部的松散代码会给你带来好处,而包裹已在函数内部的代码则不会带来任何东西(除非你把引用也算上)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接