为什么不推荐“$().ready(handler)”?

IT技术 javascript jquery callback document-ready
2021-02-17 06:55:16

jQuery的API文档的网站ready

以下所有三种语法都是等效的:

  • $(document).ready(handler)
  • $().ready(handler)(不推荐这样做)
  • $(处理程序)

做完功课-阅读和玩弄源代码后,我不知道为什么

$().ready(handler) 

不推荐。第一种和第三种方式完全相同,第三种方式调用缓存的 jQuery 对象上的就绪函数document

rootjQuery = jQuery(document);
...
...

// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
    return rootjQuery.ready( selector );
}

但是ready函数与选中节点元素的selector没有交互,ready源码:

ready: function( fn ) {
    // Attach the listeners
    jQuery.bindReady();
        // Add the callback
    readyList.add( fn );
        return this;
},

如您所见,它只是将回调添加到内部 queue( readyList) 而不会更改或使用集合中的元素。这使您可以ready在每个 jQuery 对象上调用该函数。

喜欢:

  • 常规选择器:$('a').ready(handler) DEMO
  • 废话选择器:$('fdhjhjkdafdsjkjriohfjdnfj').ready(handler) DEMO
  • 未定义的选择器:$().ready(handler) DEMO

最后...我的问题:为什么$().ready(handler)不推荐?

6个回答

我从一位 jQuery 开发人员那里得到了官方答复:

$().ready(fn)之所以$()有效,是因为曾经是$(document) (jQuery <1.4)的快捷方式,
所以$().ready(fn)是可读的代码。

但是人们过去常常做类似的事情$().mouseover()以及其他各种疯狂的事情
人们必须$([])得到一个空的 jQuery 对象

所以在 1.4 我们改变了它所以$()给了一个空的 jQuery 我们只是做了$().ready(fn)工作以免破坏很多代码

$().ready(fn) 从字面上看,现在只是在核心中进行了修补,以使其在遗留案例中正常工作。

ready功能的最佳位置$.ready(fn),但这是一个非常古老的设计决策,这就是我们现在所拥有的。


我问他(过去式:

你认为 $(fn) 比 $().ready(fn) 更易读吗?!

他的回答是:

我总是在实际应用程序中执行 $(document).ready(fn) 并且通常在应用程序中只有一个文档就绪块,这与维护工作并不完全一样。

我认为 $(fn) 也很不可读,这只是你必须知道的事情™ ...

这只是你必须知道的一件事™ ......” 好吧,$(selector[, context])$(html[, ownerDocument])事实上,如果必须知道它的工作原理是问题,您不妨直接使用jQuery()而不是使用$()或者为什么要使用 jQuery?
2021-04-22 06:55:16
@Esailija:如果他们是认真的,他们也不会交换行为$()摆在首位(为愚蠢的作为行为可能已经)另一方面,你是对的。他们并不总是那么倾向于进行重大更改,正如他们尝试更改时所显示的.attr()那样,然后在几天后快速恢复。这使他们不得不做出一些不幸的早期(和中年)设计决策。
2021-04-26 06:55:16
@gdoron +1 直接从马嘴里得到它。
2021-05-04 06:55:16
@gdoron +1 以获得真正的答案。而且,是的,我们的看法已经很接近了。
2021-05-11 06:55:16
有道理,jQuery 非常重视向后兼容性
2021-05-14 06:55:16

由于不同选项的作用与您指出的几乎相同,因此是时候戴上图书馆作家的帽子并进行一些猜测了。

  1. 也许 jQuery 人希望$()将来可以使用(值得怀疑,因为$().ready有文件证明可以工作,即使不推荐;它也会污染$if special-cases的语义)。

  2. 一个更实际的原因:第二个版本是唯一一个没有结束包装的版本document,因此在维护代码时更容易破坏。例子:

    // BEFORE
    $(document).ready(foo);
    
    // AFTER: works
    $(document).ready(foo).on("click", "a", function() {});
    

    将此与

    // BEFORE
    $().ready(foo);
    
    // AFTER: breaks
    $().ready(foo).on("click", "a", function() {});
    
  3. 与上述相关:ready是一个怪胎,因为它是(唯一的?)方法,无论 jQuery 对象包装什么(即使它没有包装任何东西,就像这里的情况)一样。这是与其他 jQuery 方法的语义的主要区别,因此不鼓励特别依赖此方法。

    更新:正如 Esailja 的评论指出的那样,从工程角度来看ready,它确实应该是一个静态方法,因为它是这样工作的。

更新 #2:从源头上挖掘,似乎在 1.4 分支中的某个点$()已更改为 match $([]),而在 1.3 中它的行为类似于$(document). 这一变化将加强上述理由。

我无法理解第二次更新,您能详细说明一下吗?我搜索了旧版本,但找不到这个空 jQuery 对象问题的任何区别。
2021-04-21 06:55:16
@gdoron:我的意思是从selector = selector || document的变化if(!selector) return this
2021-04-23 06:55:16
我从来没有见过这样的代码,旧的成语是 $(document).ready( function(){ //your code here } );
2021-05-08 06:55:16

我会说它只是$()返回一个对象的事实,$(document)不会这样你适用ready()于不同的事物;它仍然有效,但我会说它不直观。

$(document).ready(function(){}).prop("title") // the title
$().ready(function(){}).prop("title")  //null - no backing document
也许是因为不推荐这种理论上的机会方法,因为它在不同的版本中具有不同的行为。
2021-04-27 06:55:16
是的,这个答案中也有同样的看法因此,更改发生在 1.4 版本中,该版本发布了新的退货政策。
2021-04-29 06:55:16
@亚历克斯K。他的观点是,实际上没有人会真正用铁链锁住,.ready因为不这样做是一个成熟的习语。当然,理论上有人这样做是有可能的,但我从未见过代码这样做(这不是一个好的论点,但你知道:D)。
2021-05-03 06:55:16
那么没有文档属性或方法可以通过链接 $()
2021-05-06 06:55:16
我从未见过有人在附加就绪回调时更改文档标题,而且您可以简单地使用 vanilla js 来完成,而无需 jQuery我不是说这不是答案,但这不是一个很好的理由。
2021-05-13 06:55:16

这很可能只是一个文档错误,应该修复,使用的唯一缺点$().ready(handler)是它的可读性。当然,争辩说$(handler)这同样不可读。我同意,这就是我不使用它的原因

您也可以争辩说一种方法比另一种方法快。但是,您在单个页面上连续多次调用此方法以注意到差异的频率如何?

最终归结为个人喜好。$().ready(handler)除了可读性参数之外,使用没有任何缺点我认为在这种情况下文档是错误的。

+1!你完全正确!你会喜欢阅读官方的 jQuery 答案。我将其添加为答案。
2021-04-15 06:55:16

只是为了清楚地表明这三种形式存在一些不一致,另外我添加了第四种常用形式: (function($) {}(jQuery));

使用此标记:

<div >one</div>
<div>two</div>
<div id='t'/>

和这个代码:

var howmanyEmpty = $().ready().find('*').length;
var howmanyHandler = $(function() {}).find('*').length;
var howmanyDoc = $(document).ready().find('*').length;
var howmanyPassed = (function($) { return $('*').length; }(jQuery));
var howmanyYuck = (function($) {}(jQuery));
var howmanyYuckType = (typeof howmanyYuck);

$(document).ready(function() {
    $('#t').text(howmanyEmpty + ":" + howmanyHandler + ":" 
        + howmanyDoc + ":" + howmanyPassed + ":" + howmanyYuckType);
});

上一条语句的div显示结果为:0:9:9:9:undefined

所以,只有 Handler 和 Doc 版本与 jQuery 约定一致,即在获取文档选择器时返回一些有用的东西,并且使用 Passed 表单,您必须返回一些东西(我认为我不会这样做,但只是把它放在显示“里面”它有东西)。

这是好奇的小提琴版本:http : //jsfiddle.net/az85G/

是的,我还没有研究过代码库的这一特定部分,我已经破解了核心以修复错误,但没有研究其中的那部分。我现在更喜欢jQuery(document).ready(function(){});在我们的代码库中看到表单,因为有不同级别的 jQuery 专业知识,对新手来说“最明显”它是 jQuery 的事件处理函数。
2021-04-22 06:55:16
原因是它更快,因为 ctor 的第一个“中断”条件是,if(!selector) return this如果你提供其他东西,就会发生regex其他事情......谢谢你的好话......我想我可能会要求 jQuery 团队回答这个(见鬼,这不是我的图书馆:-))。
2021-05-01 06:55:16
我看不出有什么用,它不是任何发现问题,你给了jQuery的背景下null使.find('*').length返回0您是否发现这种(明显的)行为不好?
2021-05-04 06:55:16
@gdoron - 我没有发现这种行为有什么不好,我只是想指出与它有一个非空的选择器相比的区别 - 请注意,这个空的选择器可能是“更快”注释被注意到的原因其他地方,因为它有一个较小的对象要处理,但在该实例中确实返回一个对象而不是“未定义”。不过我真的很喜欢这个问题,并且确实赞成它:)
2021-05-04 06:55:16