为什么不建议使用“ $()。ready(handler)”?


88

jQuery API文档站点获取ready

以下三种语法均等效:

  • $(document).ready(处理程序)
  • $()。ready(handler)(不建议这样做)
  • $(处理程序)

做完作业-阅读并使用源代码后,我不知道为什么

$().ready(handler) 

不推荐。第一种和第三种方法完全相同,第三个选项使用以下命令在缓存的jQuery对象上调用ready函数document

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

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

但是ready函数与所选节点元素的选择器没有交互作用。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)不推荐?


60
@ChaosPandion:在我看来,他似乎努力了解自己使用的工具,例如手背。我不会确切地称这种浪费的精力。
2012年

5
好问题。如果有人感兴趣,这里有一个性能比较 ... ...(至少在Chrome中显示)“不推荐”版本实际上是最快的。
詹姆斯·阿拉拉迪斯

5
一个更好的问题是为什么这些甚至根本不存在,它应该是一个静态方法($.ready例如),而不需要首先构造一个jQuery对象。
Esailija

2
@Esailija是所有观点中最好的。除非jQuery计划.ready()为单个元素提供某种功能,否则就没有理由构造jQuery对象。

2
@ChaosPandion。您不能使用... $.ready已经由内部jQuery函数使用,请在源代码中搜索ready:
gdoron支持Monica's 2012年

Answers:


88

我从一名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)也是很难读的,这只是您必须了解Works™的一件事 ...


1
从某种意义上说,jQuery非常重视向后兼容性
Esailija 2012年

@Esailija:如果他们是认真的,他们也不会交换行为$()摆在首位(为愚蠢的作为行为可能已经)。另一方面,你是对的。他们并不总是倾向于进行重大更改,就像他们尝试更改时所显示的.attr()那样,然后在几天后进行了快速还原。这使他们不得不承担一些不幸的早期(和中年)设计决策。

3
@gdoron +1,可以直接从马口中获得。

2
@gdoron +1可获取真正的答案。而且,是的,我们的看法已经非常接近。
VisioN 2012年

这只是您必须知道Works ™的一件事 ……” $(selector[, context])和也是$(html[, ownerDocument])。实际上,如果jQuery()不是$()必须要解决的问题,那么最好也使用而不是。还是为什么甚至根本不使用jQuery?
2013年

11

由于不同的选项几乎与您指出的一样,因此现在该戴上图书馆作家的帽子进行猜测了。

  1. 也许jQuery的人希望$()将来可以使用(令人怀疑的$().ready是,尽管不推荐使用,但是据记载可以正常工作;$如果使用特殊情况,它也会污染语义)。

  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方法的语义的主要区别,因此不建议特别依赖此方法。

    更新:正如Esailija的评论所指出的那样,从工程的角度来看ready,确实应该是一种静态方法,因为它的工作原理完全如此。

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


我从来没有见过像这样的代码,原来的成语是$(document).ready( function(){ //your code here } );
Esailija

我听不懂第二次更新,请详细说明一下吗?我搜索了旧版本,但是找不到这个空的jQuery对象问题。
gdoron支持Monica 2012年

@gdoron:我的意思是从更改selector = selector || documentif(!selector) return this
2012年

4

我只是说一个事实,即$()返回一个对象,而$(document)不是您将其ready()应用于其他事物。它仍然有效,但我会说它不直观。

$(document).ready(function(){}).prop("title") // the title
$().ready(function(){}).prop("title")  //null - no backing document

1
是的,这个答案也有相同的看法。因此,更改发生在1.4版中,该版本发布了新的退货政策。
VisioN 2012年

我从未见过有人在附加准备好的回调时更改文档标题,并且您可以使用不带jQuery的普通js来完成此操作。我不是说这可能不是答案,但这不是一个很好的理由。
gdoron支持Monica 2012年

那么,没有文档属性或方法可以通过$()
Alex K.

2
@AlexK。他的观点是,实际上没有人真正束缚过,.ready因为这是一个既定的习惯用法。当然有人在理论上有机会这样做,但是我从未见过代码这样做(这不是一个好参数,但您知道:D)。
Esailija

2
可能因为不建议使用这种理论上的机会方法,因为在不同的发行版中它具有不同的行为。
VisioN 2012年

3

这很可能只是一个文档错误,应该予以修复,使用的唯一缺点$().ready(handler)是可读性。当然,认为这$(handler)同样难以理解。我同意,这就是为什么我不使用它

您也可以说一种方法比另一种方法更快。但是,您在一个页面上连续多少次调用此方法以发现差异?

最终归结为个人喜好。$().ready(handler)除了可读性参数之外,使用它没有其他缺点。我认为在这种情况下,文档会导致误导。


+1!你说得对!您将喜欢阅读jQuery的官方答案。我将其添加为答案。
gdoron支持Monica 2012年

2

只是为了使这三个明显矛盾,我添加了第四个常用形式: (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的背景下null使.find('*').length返回0。您是否发现这种(明显的)行为不好?
gdoron支持Monica 2012年

@gdoron-我发现此行为没有什么不好,我只是想指出与选择器不为null的情况相比的区别-请注意,此选择器为空可能是为什么要标注“更快”的注释在其他地方,因为它有一个较小的对象要处理,但是在该实例中,DOES返回一个对象,而不是“未定义”。我真的都很喜欢,虽然这个问题,并没有给予好评吧:)
马克Schultheiss

原因是它之所以更快,是因为ctor的第一个“中断”条件是if(!selector) return this如果您提供其他东西,还有regex其他事情正在发生……感谢您的客气……我想我可能会问jQuery团队回答这个(地狱,这不是我的图书馆:-))。
gdoron支持Monica 2012年

是的,我还没有研究过代码库的这一特定部分,我已经破解了为漏洞进行内部修复的内核,但没有修复这一部分。我jQuery(document).ready(function(){});确实更喜欢在我们的代码库中看到这种形式,因为jQuery专业知识的水平各不相同,对于新手来说,这是“最明显的”,它是jQuery的事件处理函数。
Mark Schultheiss

0

我认为这实际上是为了提高可读性。

这个不那么富有表现力

$().ready(handler);

$(document).ready(handler)

也许他们正在尝试推广某种形式的惯用jQuery。


3
$(document).ready(handler)$(handler)建议的内容更具可读性...
gdoron支持Monica 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.