Why does iterating over jQuery objects with .each() not give me jQuery objects?
up vote
14
down vote
favorite
The following works as expected:
$(".foo").first().text("hi!")
...because first()
returns a jQuery object.
However, if I want to work with the text()
method for all matches, I need to do:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!")
}
)
...because each()
gives you DOM objects.
What is the design reason behind this baffling difference? How can I avoid having to build a jQuery object for each match?
jquery
add a comment |
up vote
14
down vote
favorite
The following works as expected:
$(".foo").first().text("hi!")
...because first()
returns a jQuery object.
However, if I want to work with the text()
method for all matches, I need to do:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!")
}
)
...because each()
gives you DOM objects.
What is the design reason behind this baffling difference? How can I avoid having to build a jQuery object for each match?
jquery
add a comment |
up vote
14
down vote
favorite
up vote
14
down vote
favorite
The following works as expected:
$(".foo").first().text("hi!")
...because first()
returns a jQuery object.
However, if I want to work with the text()
method for all matches, I need to do:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!")
}
)
...because each()
gives you DOM objects.
What is the design reason behind this baffling difference? How can I avoid having to build a jQuery object for each match?
jquery
The following works as expected:
$(".foo").first().text("hi!")
...because first()
returns a jQuery object.
However, if I want to work with the text()
method for all matches, I need to do:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!")
}
)
...because each()
gives you DOM objects.
What is the design reason behind this baffling difference? How can I avoid having to build a jQuery object for each match?
jquery
jquery
asked Oct 16 '10 at 15:13
badp
8,68534978
8,68534978
add a comment |
add a comment |
7 Answers
7
active
oldest
votes
up vote
12
down vote
accepted
Possibly due to performance reasons related to looping over large collections? If you only need the DOM objects, then you save cycles. If you need the jQuery object, then you can easily get that.
I typically don't provide the 2nd parameter to each, so I can use $(this).
Exactly what I was going to say, plus if first() didn't return a jQuery object, you'd have to use $($(selector).first()), which somewhat conflicts with jQuery's aim of being concise.
– Jon Cram
Oct 16 '10 at 15:25
Okay, I was under the impression that$(".foo")
made jQuery objects to begin with and they were stripped down to "basic" DOM objects when passed througheach()
. I guess that's not quite what's going on here :)
– badp
Oct 16 '10 at 15:34
@Jon - That's not correct.$(selector).first()
does return a jQuery object. You shouldn't wrap it again with$($(selector).first())
. The only jQuery method (to my knowledge) that returns a plain DOM element is.get( 0 )
when you pass it a number. Without the number argument, you get an Array of DOM elements.
– user113716
Oct 16 '10 at 16:20
@patrick dw: I was indicating what you'd have to do if first() didn't return a jQuery object, suggesting why it makes sense for first() to return a jQuery object.
– Jon Cram
Oct 16 '10 at 16:41
@Jon - Ah yes, I read too quickly. :o)
– user113716
Oct 16 '10 at 16:47
add a comment |
up vote
3
down vote
Internally jQuery call this for $("sel").each(function(){});
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
}
And the eq
is a simple slice:
eq: function( i ) {
return i === -1 ?
this.slice( i ) :
this.slice( i, +i + 1 );
}
So you can create a new each
function that instead of object[name]
will do a object:eq(i)
$("*").slice(1,2).toSource() == $("*").eq(1).toSource();
So to create your own each
:
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
callback.call( this.eq(i), i, this.eq(i) )
}
};
$("*").each2(function(i, obj) {
alert(obj); // now obj is a jQuery object
});
It seems that each3
is faster than each2
http://www.jsfiddle.net/m7pKk/2/
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = this.eq(i);
callback.call( jObj, i, jObj )
}
};
$.fn.each3 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = $(this[i]);
callback.call( jObj, i, jObj )
}
};
See this example on jsFiddle with performance measurement.
So this would work as well? :) Also I now need to do some profiling to understand whichever is faster.
– badp
Oct 16 '10 at 15:55
@badp: Yes. I don't think there is much difference onobj[i]
andobj.slice(i, i+1)
... See the example here jsfiddle.net/m7pKk
– BrunoLM
Oct 16 '10 at 16:02
@BrunoLM, actually$(".foo")[i]
returns a DOM object whereas$(".foo").eq(i)
gives a jQuery object. The pretty much the point here, and given the implementation ofeq
through slices I'm almost led to believe$($(".foo")[i])
would be faster...
– badp
Oct 16 '10 at 16:07
@badp: Indeed. jsfiddle.net/m7pKk/2
– BrunoLM
Oct 16 '10 at 16:13
Indeed, taking BrunoLM's implementation of each2 and changing it to only calleq(i)
once roughly halves the execution time -- source.
– badp
Oct 16 '10 at 16:18
|
show 2 more comments
up vote
2
down vote
There's the obvious performance hit that would be taken per iteration. Creating a new jQuery object each iteration would be much slower and probably noticeable over large collections. Quite often, you don't need the added convenience of the wrapped object, especially when accessing single attributes or properties. All too often you see cycle wasting code like $(this).is(":checked")
instead of this.checked
.
Aside from that, though, I would say that it's because it makes sense. A jQuery object typically represents a collection of DOM objects that can be any number in size. Sometimes jQuery is used purely for its selector support and event binding and not much beyond that. It doesn't make much sense to return a collection containing a single element when iterating over a collection of more elements. It makes much more sense to return a single item that you're more likely to need, the DOM element, then you can wrap it with jQuery if you want the added features. This also keeps it in line with iterating over NodeList and other types of collection.
add a comment |
up vote
1
down vote
I believe that since jQuery uses wrapper objects, the first method uses the original wrapper, and just removes all but the first element in the wrapper, thus keeping it being a jQuery object.
However, if they were to feed in a jQuery object for each of the nodes for the each()
function, they would be incurring that overhead of creating the wrapper for each one. And since you don't necessarily want that wrapper object, it would incur unnecessary overhead.
add a comment |
up vote
0
down vote
Probably because, in your example there's no reason to even use each
. Instead of:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!");
)
Just use:
$(".foo").text("hi!");
Everything is automatically plural when dealing with jQuery sets.
1
I'll need to call a function per hit that is more complicated than just a.text()
call :)
– badp
Oct 16 '10 at 18:23
But that gets right to the issue -- if you need to do something unique for each item in the set, does it even make sense to select them all together with ".foo"?
– jpsimons
Oct 16 '10 at 19:03
yes, if I want to, say, apply a mathematical function to the value in each ".foo". Same function, different input, different output.
– badp
Oct 16 '10 at 19:07
Ah, in that case I'd suggest passing a function into text(), but another poster probably already suggested that. I was thinking you might be doing like$(this).text($(this).hasClass("selected") ? "selected" : "")
or something silly, in which case I'd have suggested just doing jQuery(".foo.selected") or whatever.
– jpsimons
Oct 16 '10 at 19:15
add a comment |
up vote
-1
down vote
Did you see .each vs jQuery.each
You should be able to do the following:
$('li').each(function(index) {
alert(index + ': ' + $(this).text());
});
per the first link. Try $(this)
instead of $(obj)
This is in no meaningful way different. I still need to make jQuery objects.
– badp
Oct 16 '10 at 15:28
add a comment |
up vote
-1
down vote
Try
$(".foo").each( function(idx, obj) {
$(this).text("hi!")
}
)
The$()
constructor is still there.
– badp
Oct 16 '10 at 15:29
add a comment |
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
12
down vote
accepted
Possibly due to performance reasons related to looping over large collections? If you only need the DOM objects, then you save cycles. If you need the jQuery object, then you can easily get that.
I typically don't provide the 2nd parameter to each, so I can use $(this).
Exactly what I was going to say, plus if first() didn't return a jQuery object, you'd have to use $($(selector).first()), which somewhat conflicts with jQuery's aim of being concise.
– Jon Cram
Oct 16 '10 at 15:25
Okay, I was under the impression that$(".foo")
made jQuery objects to begin with and they were stripped down to "basic" DOM objects when passed througheach()
. I guess that's not quite what's going on here :)
– badp
Oct 16 '10 at 15:34
@Jon - That's not correct.$(selector).first()
does return a jQuery object. You shouldn't wrap it again with$($(selector).first())
. The only jQuery method (to my knowledge) that returns a plain DOM element is.get( 0 )
when you pass it a number. Without the number argument, you get an Array of DOM elements.
– user113716
Oct 16 '10 at 16:20
@patrick dw: I was indicating what you'd have to do if first() didn't return a jQuery object, suggesting why it makes sense for first() to return a jQuery object.
– Jon Cram
Oct 16 '10 at 16:41
@Jon - Ah yes, I read too quickly. :o)
– user113716
Oct 16 '10 at 16:47
add a comment |
up vote
12
down vote
accepted
Possibly due to performance reasons related to looping over large collections? If you only need the DOM objects, then you save cycles. If you need the jQuery object, then you can easily get that.
I typically don't provide the 2nd parameter to each, so I can use $(this).
Exactly what I was going to say, plus if first() didn't return a jQuery object, you'd have to use $($(selector).first()), which somewhat conflicts with jQuery's aim of being concise.
– Jon Cram
Oct 16 '10 at 15:25
Okay, I was under the impression that$(".foo")
made jQuery objects to begin with and they were stripped down to "basic" DOM objects when passed througheach()
. I guess that's not quite what's going on here :)
– badp
Oct 16 '10 at 15:34
@Jon - That's not correct.$(selector).first()
does return a jQuery object. You shouldn't wrap it again with$($(selector).first())
. The only jQuery method (to my knowledge) that returns a plain DOM element is.get( 0 )
when you pass it a number. Without the number argument, you get an Array of DOM elements.
– user113716
Oct 16 '10 at 16:20
@patrick dw: I was indicating what you'd have to do if first() didn't return a jQuery object, suggesting why it makes sense for first() to return a jQuery object.
– Jon Cram
Oct 16 '10 at 16:41
@Jon - Ah yes, I read too quickly. :o)
– user113716
Oct 16 '10 at 16:47
add a comment |
up vote
12
down vote
accepted
up vote
12
down vote
accepted
Possibly due to performance reasons related to looping over large collections? If you only need the DOM objects, then you save cycles. If you need the jQuery object, then you can easily get that.
I typically don't provide the 2nd parameter to each, so I can use $(this).
Possibly due to performance reasons related to looping over large collections? If you only need the DOM objects, then you save cycles. If you need the jQuery object, then you can easily get that.
I typically don't provide the 2nd parameter to each, so I can use $(this).
answered Oct 16 '10 at 15:23
Kaleb Brasee
42.3k789104
42.3k789104
Exactly what I was going to say, plus if first() didn't return a jQuery object, you'd have to use $($(selector).first()), which somewhat conflicts with jQuery's aim of being concise.
– Jon Cram
Oct 16 '10 at 15:25
Okay, I was under the impression that$(".foo")
made jQuery objects to begin with and they were stripped down to "basic" DOM objects when passed througheach()
. I guess that's not quite what's going on here :)
– badp
Oct 16 '10 at 15:34
@Jon - That's not correct.$(selector).first()
does return a jQuery object. You shouldn't wrap it again with$($(selector).first())
. The only jQuery method (to my knowledge) that returns a plain DOM element is.get( 0 )
when you pass it a number. Without the number argument, you get an Array of DOM elements.
– user113716
Oct 16 '10 at 16:20
@patrick dw: I was indicating what you'd have to do if first() didn't return a jQuery object, suggesting why it makes sense for first() to return a jQuery object.
– Jon Cram
Oct 16 '10 at 16:41
@Jon - Ah yes, I read too quickly. :o)
– user113716
Oct 16 '10 at 16:47
add a comment |
Exactly what I was going to say, plus if first() didn't return a jQuery object, you'd have to use $($(selector).first()), which somewhat conflicts with jQuery's aim of being concise.
– Jon Cram
Oct 16 '10 at 15:25
Okay, I was under the impression that$(".foo")
made jQuery objects to begin with and they were stripped down to "basic" DOM objects when passed througheach()
. I guess that's not quite what's going on here :)
– badp
Oct 16 '10 at 15:34
@Jon - That's not correct.$(selector).first()
does return a jQuery object. You shouldn't wrap it again with$($(selector).first())
. The only jQuery method (to my knowledge) that returns a plain DOM element is.get( 0 )
when you pass it a number. Without the number argument, you get an Array of DOM elements.
– user113716
Oct 16 '10 at 16:20
@patrick dw: I was indicating what you'd have to do if first() didn't return a jQuery object, suggesting why it makes sense for first() to return a jQuery object.
– Jon Cram
Oct 16 '10 at 16:41
@Jon - Ah yes, I read too quickly. :o)
– user113716
Oct 16 '10 at 16:47
Exactly what I was going to say, plus if first() didn't return a jQuery object, you'd have to use $($(selector).first()), which somewhat conflicts with jQuery's aim of being concise.
– Jon Cram
Oct 16 '10 at 15:25
Exactly what I was going to say, plus if first() didn't return a jQuery object, you'd have to use $($(selector).first()), which somewhat conflicts with jQuery's aim of being concise.
– Jon Cram
Oct 16 '10 at 15:25
Okay, I was under the impression that
$(".foo")
made jQuery objects to begin with and they were stripped down to "basic" DOM objects when passed through each()
. I guess that's not quite what's going on here :)– badp
Oct 16 '10 at 15:34
Okay, I was under the impression that
$(".foo")
made jQuery objects to begin with and they were stripped down to "basic" DOM objects when passed through each()
. I guess that's not quite what's going on here :)– badp
Oct 16 '10 at 15:34
@Jon - That's not correct.
$(selector).first()
does return a jQuery object. You shouldn't wrap it again with $($(selector).first())
. The only jQuery method (to my knowledge) that returns a plain DOM element is .get( 0 )
when you pass it a number. Without the number argument, you get an Array of DOM elements.– user113716
Oct 16 '10 at 16:20
@Jon - That's not correct.
$(selector).first()
does return a jQuery object. You shouldn't wrap it again with $($(selector).first())
. The only jQuery method (to my knowledge) that returns a plain DOM element is .get( 0 )
when you pass it a number. Without the number argument, you get an Array of DOM elements.– user113716
Oct 16 '10 at 16:20
@patrick dw: I was indicating what you'd have to do if first() didn't return a jQuery object, suggesting why it makes sense for first() to return a jQuery object.
– Jon Cram
Oct 16 '10 at 16:41
@patrick dw: I was indicating what you'd have to do if first() didn't return a jQuery object, suggesting why it makes sense for first() to return a jQuery object.
– Jon Cram
Oct 16 '10 at 16:41
@Jon - Ah yes, I read too quickly. :o)
– user113716
Oct 16 '10 at 16:47
@Jon - Ah yes, I read too quickly. :o)
– user113716
Oct 16 '10 at 16:47
add a comment |
up vote
3
down vote
Internally jQuery call this for $("sel").each(function(){});
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
}
And the eq
is a simple slice:
eq: function( i ) {
return i === -1 ?
this.slice( i ) :
this.slice( i, +i + 1 );
}
So you can create a new each
function that instead of object[name]
will do a object:eq(i)
$("*").slice(1,2).toSource() == $("*").eq(1).toSource();
So to create your own each
:
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
callback.call( this.eq(i), i, this.eq(i) )
}
};
$("*").each2(function(i, obj) {
alert(obj); // now obj is a jQuery object
});
It seems that each3
is faster than each2
http://www.jsfiddle.net/m7pKk/2/
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = this.eq(i);
callback.call( jObj, i, jObj )
}
};
$.fn.each3 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = $(this[i]);
callback.call( jObj, i, jObj )
}
};
See this example on jsFiddle with performance measurement.
So this would work as well? :) Also I now need to do some profiling to understand whichever is faster.
– badp
Oct 16 '10 at 15:55
@badp: Yes. I don't think there is much difference onobj[i]
andobj.slice(i, i+1)
... See the example here jsfiddle.net/m7pKk
– BrunoLM
Oct 16 '10 at 16:02
@BrunoLM, actually$(".foo")[i]
returns a DOM object whereas$(".foo").eq(i)
gives a jQuery object. The pretty much the point here, and given the implementation ofeq
through slices I'm almost led to believe$($(".foo")[i])
would be faster...
– badp
Oct 16 '10 at 16:07
@badp: Indeed. jsfiddle.net/m7pKk/2
– BrunoLM
Oct 16 '10 at 16:13
Indeed, taking BrunoLM's implementation of each2 and changing it to only calleq(i)
once roughly halves the execution time -- source.
– badp
Oct 16 '10 at 16:18
|
show 2 more comments
up vote
3
down vote
Internally jQuery call this for $("sel").each(function(){});
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
}
And the eq
is a simple slice:
eq: function( i ) {
return i === -1 ?
this.slice( i ) :
this.slice( i, +i + 1 );
}
So you can create a new each
function that instead of object[name]
will do a object:eq(i)
$("*").slice(1,2).toSource() == $("*").eq(1).toSource();
So to create your own each
:
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
callback.call( this.eq(i), i, this.eq(i) )
}
};
$("*").each2(function(i, obj) {
alert(obj); // now obj is a jQuery object
});
It seems that each3
is faster than each2
http://www.jsfiddle.net/m7pKk/2/
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = this.eq(i);
callback.call( jObj, i, jObj )
}
};
$.fn.each3 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = $(this[i]);
callback.call( jObj, i, jObj )
}
};
See this example on jsFiddle with performance measurement.
So this would work as well? :) Also I now need to do some profiling to understand whichever is faster.
– badp
Oct 16 '10 at 15:55
@badp: Yes. I don't think there is much difference onobj[i]
andobj.slice(i, i+1)
... See the example here jsfiddle.net/m7pKk
– BrunoLM
Oct 16 '10 at 16:02
@BrunoLM, actually$(".foo")[i]
returns a DOM object whereas$(".foo").eq(i)
gives a jQuery object. The pretty much the point here, and given the implementation ofeq
through slices I'm almost led to believe$($(".foo")[i])
would be faster...
– badp
Oct 16 '10 at 16:07
@badp: Indeed. jsfiddle.net/m7pKk/2
– BrunoLM
Oct 16 '10 at 16:13
Indeed, taking BrunoLM's implementation of each2 and changing it to only calleq(i)
once roughly halves the execution time -- source.
– badp
Oct 16 '10 at 16:18
|
show 2 more comments
up vote
3
down vote
up vote
3
down vote
Internally jQuery call this for $("sel").each(function(){});
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
}
And the eq
is a simple slice:
eq: function( i ) {
return i === -1 ?
this.slice( i ) :
this.slice( i, +i + 1 );
}
So you can create a new each
function that instead of object[name]
will do a object:eq(i)
$("*").slice(1,2).toSource() == $("*").eq(1).toSource();
So to create your own each
:
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
callback.call( this.eq(i), i, this.eq(i) )
}
};
$("*").each2(function(i, obj) {
alert(obj); // now obj is a jQuery object
});
It seems that each3
is faster than each2
http://www.jsfiddle.net/m7pKk/2/
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = this.eq(i);
callback.call( jObj, i, jObj )
}
};
$.fn.each3 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = $(this[i]);
callback.call( jObj, i, jObj )
}
};
See this example on jsFiddle with performance measurement.
Internally jQuery call this for $("sel").each(function(){});
if ( isObj ) {
for ( name in object ) {
if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
break;
}
}
}
And the eq
is a simple slice:
eq: function( i ) {
return i === -1 ?
this.slice( i ) :
this.slice( i, +i + 1 );
}
So you can create a new each
function that instead of object[name]
will do a object:eq(i)
$("*").slice(1,2).toSource() == $("*").eq(1).toSource();
So to create your own each
:
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
callback.call( this.eq(i), i, this.eq(i) )
}
};
$("*").each2(function(i, obj) {
alert(obj); // now obj is a jQuery object
});
It seems that each3
is faster than each2
http://www.jsfiddle.net/m7pKk/2/
$.fn.each2 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = this.eq(i);
callback.call( jObj, i, jObj )
}
};
$.fn.each3 = function(callback)
{
for ( var i = 0; i < this.length; ++i ) {
var jObj = $(this[i]);
callback.call( jObj, i, jObj )
}
};
See this example on jsFiddle with performance measurement.
edited Oct 16 '10 at 16:11
answered Oct 16 '10 at 15:44
BrunoLM
58.4k63222381
58.4k63222381
So this would work as well? :) Also I now need to do some profiling to understand whichever is faster.
– badp
Oct 16 '10 at 15:55
@badp: Yes. I don't think there is much difference onobj[i]
andobj.slice(i, i+1)
... See the example here jsfiddle.net/m7pKk
– BrunoLM
Oct 16 '10 at 16:02
@BrunoLM, actually$(".foo")[i]
returns a DOM object whereas$(".foo").eq(i)
gives a jQuery object. The pretty much the point here, and given the implementation ofeq
through slices I'm almost led to believe$($(".foo")[i])
would be faster...
– badp
Oct 16 '10 at 16:07
@badp: Indeed. jsfiddle.net/m7pKk/2
– BrunoLM
Oct 16 '10 at 16:13
Indeed, taking BrunoLM's implementation of each2 and changing it to only calleq(i)
once roughly halves the execution time -- source.
– badp
Oct 16 '10 at 16:18
|
show 2 more comments
So this would work as well? :) Also I now need to do some profiling to understand whichever is faster.
– badp
Oct 16 '10 at 15:55
@badp: Yes. I don't think there is much difference onobj[i]
andobj.slice(i, i+1)
... See the example here jsfiddle.net/m7pKk
– BrunoLM
Oct 16 '10 at 16:02
@BrunoLM, actually$(".foo")[i]
returns a DOM object whereas$(".foo").eq(i)
gives a jQuery object. The pretty much the point here, and given the implementation ofeq
through slices I'm almost led to believe$($(".foo")[i])
would be faster...
– badp
Oct 16 '10 at 16:07
@badp: Indeed. jsfiddle.net/m7pKk/2
– BrunoLM
Oct 16 '10 at 16:13
Indeed, taking BrunoLM's implementation of each2 and changing it to only calleq(i)
once roughly halves the execution time -- source.
– badp
Oct 16 '10 at 16:18
So this would work as well? :) Also I now need to do some profiling to understand whichever is faster.
– badp
Oct 16 '10 at 15:55
So this would work as well? :) Also I now need to do some profiling to understand whichever is faster.
– badp
Oct 16 '10 at 15:55
@badp: Yes. I don't think there is much difference on
obj[i]
and obj.slice(i, i+1)
... See the example here jsfiddle.net/m7pKk– BrunoLM
Oct 16 '10 at 16:02
@badp: Yes. I don't think there is much difference on
obj[i]
and obj.slice(i, i+1)
... See the example here jsfiddle.net/m7pKk– BrunoLM
Oct 16 '10 at 16:02
@BrunoLM, actually
$(".foo")[i]
returns a DOM object whereas $(".foo").eq(i)
gives a jQuery object. The pretty much the point here, and given the implementation of eq
through slices I'm almost led to believe $($(".foo")[i])
would be faster...– badp
Oct 16 '10 at 16:07
@BrunoLM, actually
$(".foo")[i]
returns a DOM object whereas $(".foo").eq(i)
gives a jQuery object. The pretty much the point here, and given the implementation of eq
through slices I'm almost led to believe $($(".foo")[i])
would be faster...– badp
Oct 16 '10 at 16:07
@badp: Indeed. jsfiddle.net/m7pKk/2
– BrunoLM
Oct 16 '10 at 16:13
@badp: Indeed. jsfiddle.net/m7pKk/2
– BrunoLM
Oct 16 '10 at 16:13
Indeed, taking BrunoLM's implementation of each2 and changing it to only call
eq(i)
once roughly halves the execution time -- source.– badp
Oct 16 '10 at 16:18
Indeed, taking BrunoLM's implementation of each2 and changing it to only call
eq(i)
once roughly halves the execution time -- source.– badp
Oct 16 '10 at 16:18
|
show 2 more comments
up vote
2
down vote
There's the obvious performance hit that would be taken per iteration. Creating a new jQuery object each iteration would be much slower and probably noticeable over large collections. Quite often, you don't need the added convenience of the wrapped object, especially when accessing single attributes or properties. All too often you see cycle wasting code like $(this).is(":checked")
instead of this.checked
.
Aside from that, though, I would say that it's because it makes sense. A jQuery object typically represents a collection of DOM objects that can be any number in size. Sometimes jQuery is used purely for its selector support and event binding and not much beyond that. It doesn't make much sense to return a collection containing a single element when iterating over a collection of more elements. It makes much more sense to return a single item that you're more likely to need, the DOM element, then you can wrap it with jQuery if you want the added features. This also keeps it in line with iterating over NodeList and other types of collection.
add a comment |
up vote
2
down vote
There's the obvious performance hit that would be taken per iteration. Creating a new jQuery object each iteration would be much slower and probably noticeable over large collections. Quite often, you don't need the added convenience of the wrapped object, especially when accessing single attributes or properties. All too often you see cycle wasting code like $(this).is(":checked")
instead of this.checked
.
Aside from that, though, I would say that it's because it makes sense. A jQuery object typically represents a collection of DOM objects that can be any number in size. Sometimes jQuery is used purely for its selector support and event binding and not much beyond that. It doesn't make much sense to return a collection containing a single element when iterating over a collection of more elements. It makes much more sense to return a single item that you're more likely to need, the DOM element, then you can wrap it with jQuery if you want the added features. This also keeps it in line with iterating over NodeList and other types of collection.
add a comment |
up vote
2
down vote
up vote
2
down vote
There's the obvious performance hit that would be taken per iteration. Creating a new jQuery object each iteration would be much slower and probably noticeable over large collections. Quite often, you don't need the added convenience of the wrapped object, especially when accessing single attributes or properties. All too often you see cycle wasting code like $(this).is(":checked")
instead of this.checked
.
Aside from that, though, I would say that it's because it makes sense. A jQuery object typically represents a collection of DOM objects that can be any number in size. Sometimes jQuery is used purely for its selector support and event binding and not much beyond that. It doesn't make much sense to return a collection containing a single element when iterating over a collection of more elements. It makes much more sense to return a single item that you're more likely to need, the DOM element, then you can wrap it with jQuery if you want the added features. This also keeps it in line with iterating over NodeList and other types of collection.
There's the obvious performance hit that would be taken per iteration. Creating a new jQuery object each iteration would be much slower and probably noticeable over large collections. Quite often, you don't need the added convenience of the wrapped object, especially when accessing single attributes or properties. All too often you see cycle wasting code like $(this).is(":checked")
instead of this.checked
.
Aside from that, though, I would say that it's because it makes sense. A jQuery object typically represents a collection of DOM objects that can be any number in size. Sometimes jQuery is used purely for its selector support and event binding and not much beyond that. It doesn't make much sense to return a collection containing a single element when iterating over a collection of more elements. It makes much more sense to return a single item that you're more likely to need, the DOM element, then you can wrap it with jQuery if you want the added features. This also keeps it in line with iterating over NodeList and other types of collection.
edited Oct 16 '10 at 18:04
answered Oct 16 '10 at 17:55
Andy E
258k64415417
258k64415417
add a comment |
add a comment |
up vote
1
down vote
I believe that since jQuery uses wrapper objects, the first method uses the original wrapper, and just removes all but the first element in the wrapper, thus keeping it being a jQuery object.
However, if they were to feed in a jQuery object for each of the nodes for the each()
function, they would be incurring that overhead of creating the wrapper for each one. And since you don't necessarily want that wrapper object, it would incur unnecessary overhead.
add a comment |
up vote
1
down vote
I believe that since jQuery uses wrapper objects, the first method uses the original wrapper, and just removes all but the first element in the wrapper, thus keeping it being a jQuery object.
However, if they were to feed in a jQuery object for each of the nodes for the each()
function, they would be incurring that overhead of creating the wrapper for each one. And since you don't necessarily want that wrapper object, it would incur unnecessary overhead.
add a comment |
up vote
1
down vote
up vote
1
down vote
I believe that since jQuery uses wrapper objects, the first method uses the original wrapper, and just removes all but the first element in the wrapper, thus keeping it being a jQuery object.
However, if they were to feed in a jQuery object for each of the nodes for the each()
function, they would be incurring that overhead of creating the wrapper for each one. And since you don't necessarily want that wrapper object, it would incur unnecessary overhead.
I believe that since jQuery uses wrapper objects, the first method uses the original wrapper, and just removes all but the first element in the wrapper, thus keeping it being a jQuery object.
However, if they were to feed in a jQuery object for each of the nodes for the each()
function, they would be incurring that overhead of creating the wrapper for each one. And since you don't necessarily want that wrapper object, it would incur unnecessary overhead.
answered Oct 16 '10 at 15:24
Thomas
3,82631818
3,82631818
add a comment |
add a comment |
up vote
0
down vote
Probably because, in your example there's no reason to even use each
. Instead of:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!");
)
Just use:
$(".foo").text("hi!");
Everything is automatically plural when dealing with jQuery sets.
1
I'll need to call a function per hit that is more complicated than just a.text()
call :)
– badp
Oct 16 '10 at 18:23
But that gets right to the issue -- if you need to do something unique for each item in the set, does it even make sense to select them all together with ".foo"?
– jpsimons
Oct 16 '10 at 19:03
yes, if I want to, say, apply a mathematical function to the value in each ".foo". Same function, different input, different output.
– badp
Oct 16 '10 at 19:07
Ah, in that case I'd suggest passing a function into text(), but another poster probably already suggested that. I was thinking you might be doing like$(this).text($(this).hasClass("selected") ? "selected" : "")
or something silly, in which case I'd have suggested just doing jQuery(".foo.selected") or whatever.
– jpsimons
Oct 16 '10 at 19:15
add a comment |
up vote
0
down vote
Probably because, in your example there's no reason to even use each
. Instead of:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!");
)
Just use:
$(".foo").text("hi!");
Everything is automatically plural when dealing with jQuery sets.
1
I'll need to call a function per hit that is more complicated than just a.text()
call :)
– badp
Oct 16 '10 at 18:23
But that gets right to the issue -- if you need to do something unique for each item in the set, does it even make sense to select them all together with ".foo"?
– jpsimons
Oct 16 '10 at 19:03
yes, if I want to, say, apply a mathematical function to the value in each ".foo". Same function, different input, different output.
– badp
Oct 16 '10 at 19:07
Ah, in that case I'd suggest passing a function into text(), but another poster probably already suggested that. I was thinking you might be doing like$(this).text($(this).hasClass("selected") ? "selected" : "")
or something silly, in which case I'd have suggested just doing jQuery(".foo.selected") or whatever.
– jpsimons
Oct 16 '10 at 19:15
add a comment |
up vote
0
down vote
up vote
0
down vote
Probably because, in your example there's no reason to even use each
. Instead of:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!");
)
Just use:
$(".foo").text("hi!");
Everything is automatically plural when dealing with jQuery sets.
Probably because, in your example there's no reason to even use each
. Instead of:
$(".foo").each( function(idx, obj) {
$(obj).text("hi!");
)
Just use:
$(".foo").text("hi!");
Everything is automatically plural when dealing with jQuery sets.
edited Oct 16 '10 at 19:03
Josh
8,90085496
8,90085496
answered Oct 16 '10 at 18:04
jpsimons
19.1k32843
19.1k32843
1
I'll need to call a function per hit that is more complicated than just a.text()
call :)
– badp
Oct 16 '10 at 18:23
But that gets right to the issue -- if you need to do something unique for each item in the set, does it even make sense to select them all together with ".foo"?
– jpsimons
Oct 16 '10 at 19:03
yes, if I want to, say, apply a mathematical function to the value in each ".foo". Same function, different input, different output.
– badp
Oct 16 '10 at 19:07
Ah, in that case I'd suggest passing a function into text(), but another poster probably already suggested that. I was thinking you might be doing like$(this).text($(this).hasClass("selected") ? "selected" : "")
or something silly, in which case I'd have suggested just doing jQuery(".foo.selected") or whatever.
– jpsimons
Oct 16 '10 at 19:15
add a comment |
1
I'll need to call a function per hit that is more complicated than just a.text()
call :)
– badp
Oct 16 '10 at 18:23
But that gets right to the issue -- if you need to do something unique for each item in the set, does it even make sense to select them all together with ".foo"?
– jpsimons
Oct 16 '10 at 19:03
yes, if I want to, say, apply a mathematical function to the value in each ".foo". Same function, different input, different output.
– badp
Oct 16 '10 at 19:07
Ah, in that case I'd suggest passing a function into text(), but another poster probably already suggested that. I was thinking you might be doing like$(this).text($(this).hasClass("selected") ? "selected" : "")
or something silly, in which case I'd have suggested just doing jQuery(".foo.selected") or whatever.
– jpsimons
Oct 16 '10 at 19:15
1
1
I'll need to call a function per hit that is more complicated than just a
.text()
call :)– badp
Oct 16 '10 at 18:23
I'll need to call a function per hit that is more complicated than just a
.text()
call :)– badp
Oct 16 '10 at 18:23
But that gets right to the issue -- if you need to do something unique for each item in the set, does it even make sense to select them all together with ".foo"?
– jpsimons
Oct 16 '10 at 19:03
But that gets right to the issue -- if you need to do something unique for each item in the set, does it even make sense to select them all together with ".foo"?
– jpsimons
Oct 16 '10 at 19:03
yes, if I want to, say, apply a mathematical function to the value in each ".foo". Same function, different input, different output.
– badp
Oct 16 '10 at 19:07
yes, if I want to, say, apply a mathematical function to the value in each ".foo". Same function, different input, different output.
– badp
Oct 16 '10 at 19:07
Ah, in that case I'd suggest passing a function into text(), but another poster probably already suggested that. I was thinking you might be doing like
$(this).text($(this).hasClass("selected") ? "selected" : "")
or something silly, in which case I'd have suggested just doing jQuery(".foo.selected") or whatever.– jpsimons
Oct 16 '10 at 19:15
Ah, in that case I'd suggest passing a function into text(), but another poster probably already suggested that. I was thinking you might be doing like
$(this).text($(this).hasClass("selected") ? "selected" : "")
or something silly, in which case I'd have suggested just doing jQuery(".foo.selected") or whatever.– jpsimons
Oct 16 '10 at 19:15
add a comment |
up vote
-1
down vote
Did you see .each vs jQuery.each
You should be able to do the following:
$('li').each(function(index) {
alert(index + ': ' + $(this).text());
});
per the first link. Try $(this)
instead of $(obj)
This is in no meaningful way different. I still need to make jQuery objects.
– badp
Oct 16 '10 at 15:28
add a comment |
up vote
-1
down vote
Did you see .each vs jQuery.each
You should be able to do the following:
$('li').each(function(index) {
alert(index + ': ' + $(this).text());
});
per the first link. Try $(this)
instead of $(obj)
This is in no meaningful way different. I still need to make jQuery objects.
– badp
Oct 16 '10 at 15:28
add a comment |
up vote
-1
down vote
up vote
-1
down vote
Did you see .each vs jQuery.each
You should be able to do the following:
$('li').each(function(index) {
alert(index + ': ' + $(this).text());
});
per the first link. Try $(this)
instead of $(obj)
Did you see .each vs jQuery.each
You should be able to do the following:
$('li').each(function(index) {
alert(index + ': ' + $(this).text());
});
per the first link. Try $(this)
instead of $(obj)
answered Oct 16 '10 at 15:22
Anon
96721223
96721223
This is in no meaningful way different. I still need to make jQuery objects.
– badp
Oct 16 '10 at 15:28
add a comment |
This is in no meaningful way different. I still need to make jQuery objects.
– badp
Oct 16 '10 at 15:28
This is in no meaningful way different. I still need to make jQuery objects.
– badp
Oct 16 '10 at 15:28
This is in no meaningful way different. I still need to make jQuery objects.
– badp
Oct 16 '10 at 15:28
add a comment |
up vote
-1
down vote
Try
$(".foo").each( function(idx, obj) {
$(this).text("hi!")
}
)
The$()
constructor is still there.
– badp
Oct 16 '10 at 15:29
add a comment |
up vote
-1
down vote
Try
$(".foo").each( function(idx, obj) {
$(this).text("hi!")
}
)
The$()
constructor is still there.
– badp
Oct 16 '10 at 15:29
add a comment |
up vote
-1
down vote
up vote
-1
down vote
Try
$(".foo").each( function(idx, obj) {
$(this).text("hi!")
}
)
Try
$(".foo").each( function(idx, obj) {
$(this).text("hi!")
}
)
answered Oct 16 '10 at 15:22
GôTô
7,21032741
7,21032741
The$()
constructor is still there.
– badp
Oct 16 '10 at 15:29
add a comment |
The$()
constructor is still there.
– badp
Oct 16 '10 at 15:29
The
$()
constructor is still there.– badp
Oct 16 '10 at 15:29
The
$()
constructor is still there.– badp
Oct 16 '10 at 15:29
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3949445%2fwhy-does-iterating-over-jquery-objects-with-each-not-give-me-jquery-objects%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown