21

jQuery.eachそうでなければ優れた機能が(現在の)ネイティブとは異なるように設計されているのはなぜArray.forEachですか? 例:

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

これは絶対に理にかなっています。しかし、jQuery はindex最初の引数として配置することを選択しました。

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

この設計上の決定の背後にある理由を知っている人はいますか? 私は常に$.each広範囲に使用してきましたが、インデックスはめったに使用されないため、最初の引数であることに常に悩まされていました。jQueryが直接参照を実装していることは知っていますが、そうするとthis非常に混乱します:

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

それほど気になるわけではありませんが、最も一般的な新しい配列関数にはネイティブのポリフィルを使用することを好みますが、設計上の決定について常に興味を持っていました。ブラウザがネイティブforEachとレガシーサポートを実装する前に、古い時代に作成されたのかもしれません。それとも...?

それとも、ネイティブオブジェクトでも使用できるため、このように設計されているので、コールバックの値の前にキーを配置するのが「理にかなっています」...?

補足:underscore.js(およびおそらく他のライブラリ)が逆の方法で実行することを知っています(ネイティブ関数により似ています)。

4

3 に答える 3

15

これについては、レシグ氏自身に説明を求める必要があると思います。実際のところ、ECMAscript 262 エディション 5は、jQuery が設計および開発された時点ではあまり普及していませんでした。そして、そのように設計されていたので、後で変更して既存のコードをすべて壊したくありませんでした。

実際、 Arrayをループするときに、要素のインデックスよりも優先度の高い要素にアクセスしたい可能性がはるかに高くなります。したがって、最初にインデックスをコールバックに渡す理由について、合理的な説明はありません。

もしjQueryが今日発明されたとしても、それらはネイティブ実装の動作に従うでしょう。

一方、バグが多すぎる場合は、ショートカットを作成し、ネイティブを使用しArray.prototype.forEachて jQuery でラップされたセットを繰り返すことができます。

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

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

..そして、標準のArrayの場合は、ネイティブ プロトタイプをそのまま使用します。

実装条件は false/true を返しますが、どの部分がどのように機能するかを知る必要があります。Array.prototype.forEach で条件付きで return false を使用すると continue として扱われましたが、 $.each で条件付きで return false を使用すると、break ステートメントとして扱われました。

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>

于 2012-10-26T23:16:06.183 に答える
6

これは実際に最後の jQuery conf で言及されました。残念ながら詳細は覚えていませんが、ビデオを十分に見れば見つけることができると思います(基調講演後の質疑応答の時間だったと思いますが、引用しないでください)。とにかく誰か (Resig 自身ではないと思いますが、別の jQuery org の上級メンバー) は基本的に、「jQuery には問題があることがわかっているものがいくつかあります (「それぞれ」は彼らが示した例の 1 つです)。現在、その問題のある動作に依存しているサイトが存在するため、今すぐ変更することはできません。」

つまり本質的には、答えは彼らが悪い決定を下したということです (Resig は信じられないほどのプログラマーですが、彼でさえ完璧ではありません)。現在、jQuery を使用しているすべての人は、ライブラリが比較的高い後方互換性を維持しているため、残りの時間苦しむ必要があります。新しいバージョン (そして正直に言うと、それは良いことです: jQuery をアップグレードするたびにサイト全体を書き直す必要はありません)。

Underscore ライブラリにはeach、組み込みの と同じ署名を持つメソッドがあることにも言及する価値がありeachます。実際、Underscore のバージョンは、組み込みバージョンが存在する場合はそれを実際に使用してパフォーマンスを向上させ、ブラウザーが組み込みバージョンをサポートしていない場合はそのバージョンのみに依存しeachます。jQuery オブジェクトは単なる配列であるため、簡単に で使用できます_.each。また、Underscore には jQuery に欠けている他の多くの機能があるため、jQuery を補完する優れたライブラリです。

于 2012-10-26T23:26:34.630 に答える
1

2番目の方が理にかなっていることに同意しますが、オブジェクトまたは配列で使用できることkeyを覚えておく必要が$.eachあります。オブジェクトの場合、意味があるためキーが必要になる場合があります。

于 2012-10-26T23:26:45.880 に答える