我和一个同事一起工作,他说正确的检查方式应该是:
if ($( "#myDiv" ) && $( "#myDiv" ).length ) {
//do something
}
他错了,至少在
$( "#myDiv" ) &&
部分是错误的。jQuery 的
$(选择器)
总是返回一个对象,根据定义是真实值。因此那部分是无意义的,并且无缘无故地重新查询 DOM。
性能或延迟方面,它们是否执行相同?
无缘无故地重新查询 DOM 是浪费,但大多数情况下,这不会以任何可观察的方式产生影响,特别是对于像
$("#myDiv")
这样的 ID 选择器,它们被 jQuery 优化为调用
getElementById
(这是非常快的)。所以一方面,是有益的额外工作。另一方面,现在的浏览器非常快,你可能需要更重要的事情来处理。但它可能是多余的代码,这是更大的问题。
就一般而言:jQuery 是基于集合的。这意味着对空元素集合进行的操作是无操作的。例如:
$(".foo").addClass("bar")
如果DOM中没有.foo
元素,那么它是一个无操作(不是错误)。
所以当您关心是否匹配元素时,请检查length
。如果您不关心并且只想在它们存在时执行操作,则可以直接执行操作(但有一个重要的警告1)。
因此,基本上有三种情况:
您知道元素将在那里,因此检查是无意义的
=> 不检查
您不知道元素是否存在,但您不关心并且只想在它们存在时操作
=> 不检查
您出于其他原因关心元素是否存在
=> 进行检查
1这里有一个重要的警告:如果您调用返回jQuery对象之外的东西的jQuery函数(例如val()
或offset()
或position()
等),当您将其调用在空集合上时,它通常会返回undefined
(例外是text()
,它将返回""
[text()
在几个方面与其他函数不同;这是其中之一])。因此,编写代码时会天真地假设这些内容将在集合为空时返回您期望的内容,这将会伤害您。
例如:
if ($(".foo").offset().top > 20)
如果没有任何 .foo
元素,那么 offset()
将返回 undefined
而不是一个对象,并引发错误。
但这没关系:
$(".foo").closest(".bar").toggleClass("baz"):
因为即使没有 .foo
,closest()
仍将返回另一个空的 jQuery 集合,对其调用 toggleClass()
是无效的操作。
因此,在处理不返回 jQuery 对象的访问器时,如果您不确定是否正在处理包含至少一个元素的集合,则需要更多的防御性代码,例如:
var offset = $(".foo").offset();
if (offset && offset.top > 20)
大多数存取器(不返回 jQuery 对象的)都会这样做,包括 val()
, offset()
, position()
, css()
, ...
$( "#myDiv" )
不存在,$( "#myDiv" ).length
会返回0,因此添加第二个对$( "#myDiv" )
的检查似乎是多余的。 - Drew Kennedy$('anything')
ŚįÜŚßčÁĽąŤĘęŤĮĄšľįšłļtrue
Ծƌõ†ś≠§ŤĮ•ś£Äśü•śėĮśó†śĄŹšĻČÁöĄ„Äā - Jason Pif (document.getElementById('myDiv'))
进行这些类型的检查。 - Alex Char