2009-09-27 4 views
14

jQueryオブジェクトは、ネイティブプロトタイプを汚染することなく配列のように動作します。 これはどのように達成されましたか?jQueryオブジェクトはどのように配列を模倣するのですか?

数値キーを持つオブジェクトではないことがわかりました。おそらく、それぞれのメソッドを提供するだけの問題です(jQuery.prototype.indexOf = Array.prototype.indexOfなど)。

私はグーグルでソースを見ましたが、決定的な回答は見つかりませんでした。 jQueryのコードで

+3

数字キーのオブジェクトだけではないと思いますか? – Marius

+2

Firebugは、jQueryオブジェクトを配列として表示しますが、そのような手動で作成されたオブジェクトは表示しません。 – AnC

答えて

26

jQueryオブジェクトは配列のように動作しますが、実際はという配列のようなものですオブジェクトです。配列のようなオブジェクトは、lengthというプロパティを持つ数値キーを使用するオブジェクトです。つまり、native array methodsとの互換性に必要な最小値です。

jQueryのオブジェクトは、(indexOf又はreverse等)アレイ状と実際のないArrayオブジェクト、ネイティブ配列の操作は直接呼び出すことができないだけであるからです。あなたはArray.prototypeを使うことができますが、jQueryの機能を拡張することもできます。

$('div').reverse(); // TypeError: $("div").reverse is not a function 

// we can use Array.prototype though 
Array.prototype.reverse.apply($('div')); 

// or we can extend jQuery very easily 
$.fn.reverse = Array.prototype.reverse; 
$('div').reverse(); // now it works! 

Firebugには、jQueryオブジェクトの書式設定のための特別なケースは含まれていないものとします。クイック検索でFirebugメーリングリストにa relevant postと表示されます。情報がまだ正しいと仮定すると(投稿は1月からです)、有限長 spliceの場合、Firebugはオブジェクトを配列としてフォーマットします。

JQueryはこれらの基準の両方を満たしていますが、their implementation of spliceはネイティブArrayメソッドの直接コピーに過ぎません。これは文書化されていません。つまり、内部使用のためだけです。あるいは、おそらくFirebugを使ってjQueryオブジェクトをうまくフォーマットすることを目的として追加されたものです。

+0

これは素晴らしいです - ありがとう! 私はFirebugでかなり見えるようにするためにスプライスメソッドを追加することをためらっていますが、これはちょっとしたことです。 (PS:あなたのポストにはタイプミスがあります;あなたは "スプライス"の代わりに "スライス"と言います) – AnC

+0

ありがとうございました。 jQueryの1.2ブランチはそのようなメソッドを公開しないので、 'splice'メソッドがFirebug専用のjQueryに追加されたことを示唆しています。確かに、jQueryオブジェクトがFirebugの 'Arrays'としてフォーマットされていない短い時間を覚えています。もちろん、1.3のメソッドの導入はちょうど偶然の可能性があります。 –

+1

ありがとうございます - これはチャンスに面白かったです。 SafariのWebインスペクタは、オブジェクトを配列として整形するために、 'length'オブジェクトと' splice'メソッドという同じ基準を使用しているようです: 'var o; o = {length:2、splice:function(x){}}; '=>' [] '(ファイアウォールは厳密に' 'undefined、undefined''を出力します。 –

5

ルック(開発)、行139:

// Force the current matched set of elements to become 
// the specified array of elements (destroying the stack in the process) 
// You should use pushStack() in order to do this, but maintain the stack 
setArray: function(elems) { 
    // Resetting the length to 0, then using the native Array push 
    // is a super-fast way to populate an object with array-like properties 
    this.length = 0; 
    Array.prototype.push.apply(this, elems); 
     return this; 
}, 

jQueryのクエリのいずれかの結果が配列であるためです。

+0

ありがとうございます。私もこれを見ていましたが、十分ではないようです。 var MyObj = function(args){ this.length = 0; Array.prototype.push.apply(this、arguments); これを返す。 }; var obj = new MyObj( "hello"、 "world"); – AnC

+1

'this'をコンストラクタから返さないでください!また、 'var'は変数を設定しますが、値を返しません。 Firebugのようなツールでそのスニペットを実行している場合、 'var MyObj = function(args){this.length = 0; Array.prototype.push.apply(これ、arguments); }; obj = new MyObj( "hello"、 "world"); ' –

+0

私は混乱します:コンストラクタでなければ、" this "はオブジェクトではありません。実際のサンプルを提供できますか? – AnC

関連する問題