代码之家  ›  专栏  ›  技术社区  ›  Maxim Gershkovich

如果选择器对象无效,jQuery为什么不爆炸呢?

  •  71
  • Maxim Gershkovich  · 技术社区  · 14 年前

    最近使用了一些代码

    $("#divMenuContainer:visible").hide("explode");
    

    查询的结果只是它没有执行。

    显然,这是设计,有人能解释为什么这个设计选择的逻辑,而不是提出某种例外吗?

    13 回复  |  直到 6 年前
        1
  •  53
  •   Nick Craver    14 年前

    这里有几个很好的理由,“可链接性”是主要驱动力,通过链接编写非常简洁代码的能力必须不会抛出错误才能正常工作,例如:

    $("#divMenuContainer:visible").hide("explode").add("#another").fadeIn();
    

    $("#divMenuContainer:visible").live("click", function() { ... });
    

    $("#divMenuContainer:visible").find(".child").hide("explode").end().fadeOut();
    

    即使没有孩子,我们以后也可能想跳回链条,继续使用 .prevObject 返回链的引用。

    有几十个不同的例子,像这样,显示了图书馆的好处是它的方式。至于 ,来自 John Resig

    说清楚点,我不是说 链接的属性是一个很好的属性,它有很多优点。


    让我们以这一页为例,如果我们有这样的内容:

    $(".comment").click(replyToFunction);
    

    应该

    你问题中的选择者 #ID selector

    几乎没有其他人 selector 您期望有0个元素,因此在大多数情况下,如果找不到任何元素,则失败的可能性会大大降低,在类似的情况下更是如此 .live()

        2
  •  56
  •   Matt Sherman    10 年前

    查询 ,就是这样。您要求的是符合您的条件的所有“记录”(DOM元素)。结果是一组零记录。

    如果您对SQL或数组做了相同的操作,那么它在大多数语言中的行为都是相同的。零记录的集合不是错误状态。

    var things = $("invalid selector");
    $("p").text("The object is valid: " + things + " but has " + things.length + " elements.")
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <p></p>
        3
  •  8
  •   Frank Schwieterman    14 年前

    这是一个灵活性的问题。我自己也喜欢你要求的保护,你可以自己做。用途:

    jQuery.fn.single = function() {
        if (this.length != 1) {
            throw new Error("Expected 1 matching element, found " + this.length);
        }
    
        return this;
    };
    

    现在使用$(“输入:选中“).single(),保证返回单个项或给您一个错误。

        4
  •  6
  •   BGerrissen    14 年前

    jQuery()将始终返回jQuery对象,这是为了防止错误,但更重要的是:

    所以你可以写响应性代码。

    do X if Y is present
    

    这意味着您可以有一个全局初始化跨页和初始化插件,无论他们是否找到什么。

    $(function(){
        // does nothing if the page contains no element with className 'accordion'
        $('.accordion').implementAccordion();
        // usually on a single page, but we can add it to a global js file nontheless.
        $('.validate-form').implementFormValidator();
    });
    

        5
  •  5
  •   jAndy    14 年前

    它试图对你和你的客户“友好”,这反过来意味着,它很少抛出异常
    (几乎没有)

    但像往常一样,您可以轻松地将其扩展为:

    (function(_jQuery){
        jQuery = function(){
            var ret = _jQuery.apply(this, arguments);
            if(!ret.length) throw new Error('empty selector');
            return ret;
        };
    }(jQuery));
    

    Nick 在评论中说,大多数时候这是 想要的行为。如果您出于某种原因想拥有它,上面这样的代码片段应该可以做到。

        6
  •  3
  •   recursive    14 年前

    不引用任何元素的选择器仍然是合法的选择器,可能是有意的。可能是给定的选择器有时会返回元素,并且您希望能够使用这样的选择器而不会抛出运行时错误。

        7
  •  3
  •   CaffGeek    14 年前

    一个很好的例子是当你想用所有选中的复选框做某事时

    $("input:checked")
    

    所以,不用像

    var checkedInputs = $("input:checked");
    if (checkedInputs  && checkedInputs .length > 0) {
          checkedInputs .doStuff();
    }
    

    你可以

    $("input:checked").doStuff();
    

    如果他们做出了选择,很好,事情就完成了。如果不是。。。没有伤害,没有犯规。

        8
  •  2
  •   Stefanvds    14 年前

    $("#thisdivdoesntexist") in jQuery仍然返回一个“空”jQuery Object

    这其实是件好事。如果这是抛出一个错误,那么在很多情况下,在做一些事情之前,您需要进行一些额外的检查,这意味着您将有很多“重载”代码。尽管在调用对象上的方法之前检查它是否存在并不是一种不好的做法,但是当选择器返回nothing时,并不是所有的javascript都会停止(如果它抛出错误就会发生这种情况)

        9
  •  1
  •   Chris Barr    14 年前

    通常,我只在元素存在的情况下继续执行以下操作:

    var aThing = $("#myElement");
    if(aThing.length){
        //my code here
    }
    
        10
  •  0
  •   Paddy    14 年前

    我认为这可能与您的选择器:

    $("#divMenuContainer:visible")
    

    Under the covers返回一个jQuery对象,其中包含许多可能的匹配项。然后对其中的每一个执行隐藏功能。我想在这种情况下不抛出异常是有一定意义的,因为您有一个条目为零的列表,而不是返回null。

        11
  •  0
  •   gnarf    14 年前

    这对我来说很有意义。。。如果您的选择器与任何元素都不匹配,您仍然可以调用所有正常的jQuery原型函数而不会产生错误!最坏的情况是,最终得到一个“空”jQuery集,将更改应用于no元素。

        12
  •  0
  •   PeterJ    14 年前

    我猜因为它将用于前端,所以终端用户不应该看到异常,因为开发人员编写了一些糟糕的代码。在这种情况下,无声地失败可能更安全。

        13
  •  0
  •   JD Isaacks    14 年前