What is the difference between webkit's `$$` return and jQuery `$` return?
Asked Answered
S

6

7

If in a webkit browser like Chrome i do:

$$('span');

I get a result that looks almost exactly the same as jQuery's:

$('span');

If in the console I look for definition of $$ I get:

bound: function ()
{
    return document.querySelectorAll.apply(document, arguments)
}

And for $ I get:

function (a,b){return new c.fn.init(a,b)}

What type of functions can I do on a $$ object that I cannot really do with a jQuery ($) object?

Sweeting answered 6/7, 2011 at 17:46 Comment(4)
If you try to get $ on a site without jQuery, it is a wrapper for document.getElementById().Heterotopia
@bazmegakapa -- interesting, yes it is. hmmmSweeting
+1: great question. wow! i didn't know. and also if you try $ on google search results you get return document.getElementById.apply(document, arguments) and on a page with no javascript libraries you get return document.getElementById(id);Befog
developers.google.com/chrome-developer-tools/docs/…Cy
D
3

Since $$ is just a wrapper for querySelectorAll, you can pass any valid selectors.

"What type of functions can I do on a $$ object that I cannot really do with a jQuery ($) object?"

First, $$ isn't an object like jQuery. It is an object, but it's just a simple function object that is a wrapper (shortcut) for document.querySelectorAll. It returns a NodeList of the elements it found.

The only thing it supports that Sizzle doesn't specifically support, to my knowledge, is :nth-of-type.

(Of course Sizzle defaults to qsa when you give a valid selector, so you can pass nth-of-type to the jQuery function in browsers that also support qsa.)

With Sizzle, there are several selectors that are not supported by querySelectorAll, so you can technically do more with jQuery/Sizzle.

Those include:

  • :eq()
  • :gt()
  • :lt()
  • :first
  • :last
  • :not() (When you give it multiple selectors. Simple :not() values are supported in qsa.)
  • :animated
  • :input
  • :button
  • :checkbox
  • :even
  • :odd
  • :has()
  • :image
  • :password
  • :radio
  • :reset
  • :selected
  • :submit
  • :text
  • :visible

...to name a few several.


Keep in mind that Sizzle first tries to use querySelectorAll. If you passed a proprietary selector, it then defaults to Sizzle's own engine.

Since qsa is typically faster than Sizzle, it may be advisable to consider alternatives to the proprietary selectors listed above in order to improve performance.


Also note that Webkit does not define $$ anywhere except for in the console. the $$ shortcut is not available in your scripts unless you make it available.

Dovetail answered 6/7, 2011 at 17:57 Comment(8)
If Sizzle is using qSA anyway, then what is the difference in the return? does that mean i can do jQuery functions (like .css, .html, etc...) on a qSA NodeList?Sweeting
@Neal: Sizzle is only using it for the DOM selection. That's all it's for. It's just like getElementsByTagName(), but it accepts CSS style selectors instead of just tags. What jQuery does is it takes the result of the selection, and drops it into your jQuery object, which holds all the methods like .css, .html etc.Dovetail
...open your console on this page and type document.querySelectorAll( 'div > span:first-child' );, and then $$( 'div > span:first-child' );. You'll get the same result, because it's calling the same function.Dovetail
yes i realize that, but it also looks like the same result as $( 'div > span:first-child' );Sweeting
@Neal: It looks that way in the console because the console interprets a jQuery object as an Array, even though it isn't. Naturally the result of the selection will be the same, because Sizzle either uses qsa, or if it isn't available, its own JavaScript engine emulates qsa.Dovetail
...try dropping this into the console ({length:0,splice:function(){},message:"hi",3:"index"}). It shows up looking like an Array, but it clearly isn't. This is because when the console sees any object with a splice property that has a function, and a length property that has a number, it assumes it has been given an Array, and so it displays it that way.Dovetail
that is very weird. why would it do that? that means that any object I have that has a splice function and a length, i could do array functions too?Sweeting
@Neal: No, remember the console is not part of the language. It has the task of interpreting for the purpose of display whatever it has been given, and it has to do so as an add-on. And it also needs to try to be as fast and efficient as possible. So it just takes its best guess and says "hmmm... this object I've been given has splice and length, so I'll assume it's an Array when I display it". But this has absolutely no impact on what the object actually is.Dovetail
V
7

$$ is, as you said, webkit-specific and should only really be used in console. It has very similar selectors to jQuery, the difference being that it will return an array of DOM Nodes whereas jQuery will return a jQuery array

These two are identical:

$$('span');

$('span').get();

jQuery selectors are actually a bit more powerful since they add selectors that don't exist in the dom like :checkbox, :contains, etc.

Reference: JQuery Selectors

Verdure answered 6/7, 2011 at 17:50 Comment(11)
do you have documentation of that anywhere? sounds very interestingBefog
The documentation would be on querySelectorAll: developer.mozilla.org/en/DOM/document.querySelectorAllVerdure
@cwolves - i just found this link: prototypejs.org/api/utility/dollar-dollar -- it it releated?Sweeting
@Neal - That's specific to prototypejs. With prototype, the $ function maps directly to getElementByid, whereas $$ allows you to use queries.Erasmoerasmus
Prototype didn't have that last I used it -- 3 years ago or so :). Yes, it looks to be identical syntactically, though that specifically is part of the Prototype library. Any reference on CSS selectors is valid.Verdure
qSA returns a NodeList; $ returns a jQuery object; .get() returns an array. None of these are the same as each other.Sporocyst
You're right, but they're very similar to one-another. Basically a NodeList is immutable and doesn't have array ops. My point was that they return the same elements.Verdure
@cwolves: I'd just point out that Webkit only defines $$ in the console, not in the scripts you load.Dovetail
By using attribute selectors you can do :checkbox with [type=checkbox] and this is even pointed out in the jQuery :checkbox docsScutate
@Scutate - isn't that what I said??Verdure
@cwolves No actually, you said "jQuery selectors are actually a bit more powerful" but you reference functionality that already exists in vanilla selectors. Your other example of :contains is absolutely adding power to selectors as nothing like it exists in vanilla since it was deprecated and removed from the w3 proposition.Scutate
E
4

WebKit defines $$ and $ by default as shorthand references to the document.querySelectorAll. When jQuery loads, it replaces the value of $ with the jQuery function. jQuery also preserves the original $ value if you need it. WebKit does this to introduce a consistent API for querying the DOM, regardless of whether you are using jQuery or not.

The big difference is that the result of querySelectorAll is an array of DOM elements (a NodeList - thanks @lonesomeday), whereas jQuery's is the jQuery object.

Erasmoerasmus answered 6/7, 2011 at 17:53 Comment(5)
qSA does not return an array: it returns a NodeList.Sporocyst
slight clarification: a non-live NodeListVerdure
@Sporocyst - Good point, but in the javascript API, that is treated as an array.Erasmoerasmus
@Matthew Um, in what way is it treated as an array? You can do length and [0], but you can't do slice, for instance.Sporocyst
@Matthew Abbott - it's actually an "array-like" object. You can't do array ops directly on it (though things like [].slice.call(nodeList) work), and you can't modify it. There may be other differences, but those are the major two.Verdure
D
3

Since $$ is just a wrapper for querySelectorAll, you can pass any valid selectors.

"What type of functions can I do on a $$ object that I cannot really do with a jQuery ($) object?"

First, $$ isn't an object like jQuery. It is an object, but it's just a simple function object that is a wrapper (shortcut) for document.querySelectorAll. It returns a NodeList of the elements it found.

The only thing it supports that Sizzle doesn't specifically support, to my knowledge, is :nth-of-type.

(Of course Sizzle defaults to qsa when you give a valid selector, so you can pass nth-of-type to the jQuery function in browsers that also support qsa.)

With Sizzle, there are several selectors that are not supported by querySelectorAll, so you can technically do more with jQuery/Sizzle.

Those include:

  • :eq()
  • :gt()
  • :lt()
  • :first
  • :last
  • :not() (When you give it multiple selectors. Simple :not() values are supported in qsa.)
  • :animated
  • :input
  • :button
  • :checkbox
  • :even
  • :odd
  • :has()
  • :image
  • :password
  • :radio
  • :reset
  • :selected
  • :submit
  • :text
  • :visible

...to name a few several.


Keep in mind that Sizzle first tries to use querySelectorAll. If you passed a proprietary selector, it then defaults to Sizzle's own engine.

Since qsa is typically faster than Sizzle, it may be advisable to consider alternatives to the proprietary selectors listed above in order to improve performance.


Also note that Webkit does not define $$ anywhere except for in the console. the $$ shortcut is not available in your scripts unless you make it available.

Dovetail answered 6/7, 2011 at 17:57 Comment(8)
If Sizzle is using qSA anyway, then what is the difference in the return? does that mean i can do jQuery functions (like .css, .html, etc...) on a qSA NodeList?Sweeting
@Neal: Sizzle is only using it for the DOM selection. That's all it's for. It's just like getElementsByTagName(), but it accepts CSS style selectors instead of just tags. What jQuery does is it takes the result of the selection, and drops it into your jQuery object, which holds all the methods like .css, .html etc.Dovetail
...open your console on this page and type document.querySelectorAll( 'div > span:first-child' );, and then $$( 'div > span:first-child' );. You'll get the same result, because it's calling the same function.Dovetail
yes i realize that, but it also looks like the same result as $( 'div > span:first-child' );Sweeting
@Neal: It looks that way in the console because the console interprets a jQuery object as an Array, even though it isn't. Naturally the result of the selection will be the same, because Sizzle either uses qsa, or if it isn't available, its own JavaScript engine emulates qsa.Dovetail
...try dropping this into the console ({length:0,splice:function(){},message:"hi",3:"index"}). It shows up looking like an Array, but it clearly isn't. This is because when the console sees any object with a splice property that has a function, and a length property that has a number, it assumes it has been given an Array, and so it displays it that way.Dovetail
that is very weird. why would it do that? that means that any object I have that has a splice function and a length, i could do array functions too?Sweeting
@Neal: No, remember the console is not part of the language. It has the task of interpreting for the purpose of display whatever it has been given, and it has to do so as an add-on. And it also needs to try to be as fast and efficient as possible. So it just takes its best guess and says "hmmm... this object I've been given has splice and length, so I'll assume it's an Array when I display it". But this has absolutely no impact on what the object actually is.Dovetail
T
2

Looking over the chrome developer tools page, it looks like Chrome's developer tools support Firebug's command-line API (meaning that Firebug supports $$ as well).

The documentation for $$ states:

$$(selector)

Returns an array of elements that match the given CSS selector.

Which is roughly equivalent to jQuery(selector), where selector is a CSS selector and the return types will obviously be different. In short, there's probably not anything more you can do specifically with $$, but looking over Firebug's command-line API, it looks like there are some useful functions (especially if you don't have jQuery available on the page).

Thallic answered 6/7, 2011 at 17:53 Comment(0)
B
2

Here is my bit. On researching I got this from Safari docs Debugging your WebSite

The section The Command Line API says so.

In addition to the usual JavaScript methods, and the functions and variables defined in your script, you can enter some Firebug command line API’s interactively at the console. The following commands are supported interactively:

$0-$4
Variables that contain the current and previous three selected nodes in the Web Inspector.

$(id)
Returns the element with the specified ID. Similar to getElementById().

$$(selector)
Returns the array of elements that match the given CSS selector. Similar to querySelectorAll.

$x(xpath)
Returns the array of elements that match the given XPath expression.

Befog answered 6/7, 2011 at 17:59 Comment(0)
S
1

As your question shows, $$ is a wrapper around document.querySelectorAll. This means that it has the same options when you call it and that it returns the same thing.

The differences to $ (jQuery):

  • $$ supports CSS selectors as supported by the browser. $ uses querySelectorAll when it can, but it also supports some custom extensions (e.g. :has). These will not be available with $$.
  • $$ returns a static NodeList. This isn't a particularly useful creature. It behaves a bit like an array (it has a length property and you can access its members with [0] etc), but none of the normal array methods will be available. jQuery is written to provide an object to wrap the elements found, and there are lots of convenience methods. None of these will exist on the result of $$.
  • $$ will be the fastest option, pretty much always. $ will almost always be slower, and will often be much slower.

Note that the Chrome console will show the result of $ and the result of $$ as if they were arrays. Neither is; they are merely displayed like arrays because that is an easy way to conceptualise them. $$ returns a NodeList, $ a custom object.

Sporocyst answered 6/7, 2011 at 17:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.