Jump to content

Talk:Learning JavaScript

About this board

Selector performance, contexts

6
Yair rand (talkcontribs)

The optimized example given in this section is $( '#bodyContent' ).find( 'li > a' );, but wouldn't it be better to use $( 'li > a', '#bodyContent' );?

Krinkle (talkcontribs)

Although it's not bad, the syntax you proposed is slower.

What that does is, it goes through all of jQuery's initializer and eventually at the bottom it calls (literally): $( context ).find( selector ).

The reason jQuery supports the syntax is, for example, in case plugins provide a variable as context that would otherwise cause plugins from having to write code like this:

if ( context.jquery ) {
  return context.find( '...' );
} else {
  return $( ' ... ', context );
}

instead you can use:

  return $( '...', context );

And jQuery will figure it out, after it doesn't recognize the standard syntax.

However if you know what you're doing and the context is not variable but known, it's much better to just do $(context).find(selector); directly.

Dantman (talkcontribs)

That's one reason for the context argument, the other reason is more like for things like:

$( '...', someIframe.contentDocument );

The idea of passing a selector as the second parameter for context is completely and absolutely unintuitive, you end up with the first selector run being written after the second one run, it's completely different from the way a normal person should expect to read it.

No good jQuery developer will suggest or thank you for using that.

In fact it's so unwelcome that the jQuery documentation doesn't even admit the fact that jQuery will technically accept a selector there.

context
A DOM Element, Document, or jQuery to use as context
Krinkle (talkcontribs)

In that case, I'd still recomend:

$( someIframe.contentDocument ).find( '...' );

Even if it was just to make it easier to read, and easier to cache the root jQuery object, eg.:

var $root = $( someIframe.contentDocument ),
    $foos = $root.find( '#foo > .items' ),
    $bars = $root.find( '#bar > .items' );

I didn't know using a selector String as context was possible (as it isn't documented at all). That enforces even more that it shouldn't be used.

Neelasdfsd (talkcontribs)

swipe and nice bouye

Neelasdfsd (talkcontribs)

every body come vot e

Reply to "Selector performance, contexts"
Dantman (talkcontribs)

As a JS developer myself I consider relying on loose comparison here like this as a test for null/undefined to be bad practice, I'd rather not see it in our manual on how to use JS.

Krinkle (talkcontribs)

Can you elaborate on this ?

Although it's not that common, I find it very useful in handling optional arguments (ie. not given (undefined) or null was passed). jQuery uses this a lot internally as well. It's kind of like isset() in PHP.

Either way, if one is looking specifically for undefined or null, a comparison should always be strictly checking for that. But if both are values that should return true, I don't see why one would want to write two checks that accomplish the same thing.

Dantman (talkcontribs)

You're comparing something using an equality tester with an explicitly named value but relying on loose type checks to really compare it to two different values. It's a bad form that results in code that can be hard to follow.

Frankly if higher level code is passing null in situations where you would want to `== null` to treat them the same there is something fundamentally flawed with the code. There are only two valid cases to use null. A) When working with low level dom that uses it rather than undefined. B) When writing code where the difference between undefined as 'not set' and null as 'something that means nothing' is important and needs to be distinguished. And in that case you aren't testing for both. And if you do find yourself in a small part of the code where you do want to do the same thing for null or undefined in that case if you use `== null` you place it near other `=== null` that actually require only null and make the code harder to follow.

jQuery has different priorities. jQuery deals with low level dom which in various ways is flawed and buggy and inconsistent between browsers, so they do need to catch that. jQuery's source is also not a good example for code style practices, jQuery is optimised for short concise code, not code readability. Forget our practice of requiring {}'s around an if() even if it only does one thing, jQuery uses the ternary operator over 5 lines (two comments) in a way that would end with someone kicking you if you tried that anywhere in MediaWiki.

To top it off I might want to make a reminder of one of JS' oldest mistakes `typeof null === 'object'`. Sure ES-harmony is finally trying to get rid of it, but that's not really relevant since that's a harmony opt-in and we're still working with browsers that only do ES3, not even half implemented ES5.

Krinkle (talkcontribs)

Thanks.

Neelasdfsd (talkcontribs)

lucky busyu

Neelasdfsd (talkcontribs)

lalu in election

Reply to "lorem == null"

jQuery document ready shortcut confusion

5
Krinkle (talkcontribs)

Since I ended up repeating this all over the place I might as well put it here for easy reference.

The following is an example that I would describe as an Immediately-Invoked Function Expression (IIFE) that has a local $ variable as argument, and called with the global jQuery-object as first argument. Inside of that was a jQuery ready event binder to the document:

( function ( $ ) {

	$( document ).ready( function () {
		/* code here */
 	} );

}( jQuery ) );

The reason we use this is because we want to locally alias jQuery to $. If all your code needs to be within the document ready bound function, you can use the ready-call to alias your variable, no need for an extra function:

jQuery( document ).ready( function ( $ ) {
	/* code here */
} );

If you're unfamiliar with this function you may think there's something missing here. There is "( $ )" but there is no "( jQuery );", right ? Well, here's where the difference between a locally called function and a remote callback comes in. The function passed to jQuery(document).ready is not called by you, instead it is called by jQuery's internals, at the time the document is ready. It is called like this: callbackFunction( jQuery );.

Afterall, $(document).ready isn't used like $(document).ready( fn )( jQuery ); either, that would be invalid.

So that leaves one thing, what is the following ?

jQuery( function ( $ ) {
	/* code here */
} );

Before we answer that, let's make clear what the jQuery root function (or rather, jQuery.fn.init) is. It is a shortcut to following three things:

In code snippet I use the latter (document.ready binder). This shortcut also has a slight advantage of using a cached version of jQuery(document) so there's no new jQuery object constructed for it.

This post was hidden by He7d3r (history)
This post was hidden by He7d3r (history)
This post was hidden by He7d3r (history)
Neelasdfsd (talkcontribs)

history for my side

Reply to "jQuery document ready shortcut confusion"
There are no older topics