Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
172 views
in Technique[技术] by (71.8m points)

javascript - jQuery.each implementation differs from native Array.forEach

Does anyone why is the otherwise excellent jQuery.each function is designed differently from the (now) native Array.forEach? F.ex:

var arr = ['abc','def'];
arr.forEach(function(entry, index) {
    console.log(entry); // abc / def
});

This makes absolute sense. But jQuery chose to put the index as first argument:

$.each(arr, function(index, entry) {
   console.log(entry);
});

Does anyone know the reasoning behind this design decision? I have always used $.each extensively, but it always bugged me that the index was the first argument as it is rarely used. I know jQuery implemented a direct reference through this but it’s very confusing if you do:

?var arr = ['abc','def'];
$.each(arr, function() {
    console.log(this === 'abc'); // false both times, since this is a String constructor
});?????????????????????????????

Not that it bothers me so much, I prefer to use native polyfills for the most common new array functions, but I have always been curious about the design decision. Maybe it was made in older times before browsers implemented native forEach and legacy support prevented them from changing it, or...?

Or maybe, it is designed this way because is can be used on native objects too, than then it "makes sense" to put the key before value in the callback...?

Sidenote: I know underscore.js (and maybe other libraries) does it the other way around (more similar to the native function).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Well, I guess we'd have to ask Mr. Resig himself for an explanation on this. Fact is, that ECMAscript 262 edition 5 wasn't very widespread the time jQuery was designed and developed, so this definitely comes into play. And since it was designed like so, they didn't want to change it later and break all existing code.

In fact, its much more likely that you want to access an element with a higher priority, than the index of it when looping an Array. So, to me there is no reasonable explanation why you would pass in the index first into the callbacks.

Be assured, if jQuery was invented today, they would follow the native implementation behavior.

On the other hand, if it bugs you too much you can simply create a shortcut and use the native Array.prototype.forEach to iterate your jQuery wrapped sets:

var forEach = Function.prototype.call.bind( Array.prototype.forEach );

forEach( $('div'), function( node ) {
    console.log( node );
});

..and for standard Arrays, just go with their native prototype.

while implementation conditional return false/true,we must know what part work in which manner. When you use return false with condition in Array.prototype.forEach it treated as continue, but When you use return false, with condition in $.each it treated as break statement.

var listArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
var arr1 =[];var arr2=[];
var rv = true;
listArray.forEach(function(i, item) {
  if (i == 5) {
    return rv = false;
  }
 arr1.push(i)
  return rv;
});
var listArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
jQuery.each(listArray, function(i, item) {
  if (item == 5) {
    return rv = false;
  }
  arr2.push(i)
});
  console.log("forEach=>"+arr1)
  console.log("$.each=>"+arr2)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...