Why does iterating over jQuery objects with .each() not give me jQuery objects?











up vote
14
down vote

favorite
1












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?










share|improve this question


























    up vote
    14
    down vote

    favorite
    1












    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?










    share|improve this question
























      up vote
      14
      down vote

      favorite
      1









      up vote
      14
      down vote

      favorite
      1






      1





      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?










      share|improve this question













      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Oct 16 '10 at 15:13









      badp

      8,68534978




      8,68534978
























          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).






          share|improve this answer





















          • 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












          • @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


















          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.






          share|improve this answer























          • 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










          • @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










          • 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




















          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.






          share|improve this answer






























            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.






            share|improve this answer




























              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.






              share|improve this answer



















              • 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


















              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)






              share|improve this answer





















              • This is in no meaningful way different. I still need to make jQuery objects.
                – badp
                Oct 16 '10 at 15:28




















              up vote
              -1
              down vote













              Try



              $(".foo").each( function(idx, obj) {
              $(this).text("hi!")
              }
              )





              share|improve this answer





















              • The $() constructor is still there.
                – badp
                Oct 16 '10 at 15:29











              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














               

              draft saved


              draft discarded


















              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

























              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).






              share|improve this answer





















              • 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












              • @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















              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).






              share|improve this answer





















              • 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












              • @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













              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).






              share|improve this answer












              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).







              share|improve this answer












              share|improve this answer



              share|improve this answer










              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 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












              • @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










              • 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












              • @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












              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.






              share|improve this answer























              • 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










              • @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










              • 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

















              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.






              share|improve this answer























              • 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










              • @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










              • 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















              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.






              share|improve this answer














              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.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              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 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












              • @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




















              • 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










              • @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










              • 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


















              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












              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.






              share|improve this answer



























                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.






                share|improve this answer

























                  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.






                  share|improve this answer














                  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.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Oct 16 '10 at 18:04

























                  answered Oct 16 '10 at 17:55









                  Andy E

                  258k64415417




                  258k64415417






















                      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.






                      share|improve this answer

























                        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.






                        share|improve this answer























                          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.






                          share|improve this answer












                          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.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Oct 16 '10 at 15:24









                          Thomas

                          3,82631818




                          3,82631818






















                              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.






                              share|improve this answer



















                              • 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















                              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.






                              share|improve this answer



















                              • 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













                              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.






                              share|improve this answer














                              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.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              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














                              • 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










                              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)






                              share|improve this answer





















                              • This is in no meaningful way different. I still need to make jQuery objects.
                                – badp
                                Oct 16 '10 at 15:28

















                              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)






                              share|improve this answer





















                              • This is in no meaningful way different. I still need to make jQuery objects.
                                – badp
                                Oct 16 '10 at 15:28















                              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)






                              share|improve this answer












                              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)







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              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




















                              • 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












                              up vote
                              -1
                              down vote













                              Try



                              $(".foo").each( function(idx, obj) {
                              $(this).text("hi!")
                              }
                              )





                              share|improve this answer





















                              • The $() constructor is still there.
                                – badp
                                Oct 16 '10 at 15:29















                              up vote
                              -1
                              down vote













                              Try



                              $(".foo").each( function(idx, obj) {
                              $(this).text("hi!")
                              }
                              )





                              share|improve this answer





















                              • The $() constructor is still there.
                                – badp
                                Oct 16 '10 at 15:29













                              up vote
                              -1
                              down vote










                              up vote
                              -1
                              down vote









                              Try



                              $(".foo").each( function(idx, obj) {
                              $(this).text("hi!")
                              }
                              )





                              share|improve this answer












                              Try



                              $(".foo").each( function(idx, obj) {
                              $(this).text("hi!")
                              }
                              )






                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              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


















                              • 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


















                               

                              draft saved


                              draft discarded



















































                               


                              draft saved


                              draft discarded














                              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





















































                              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







                              這個網誌中的熱門文章

                              Tangent Lines Diagram Along Smooth Curve

                              Yusuf al-Mu'taman ibn Hud

                              Zucchini