ホームページ  >  記事  >  ウェブフロントエンド  >  jQuery データ キャッシュの進化の歴史の詳細な紹介 module_jquery

jQuery データ キャッシュの進化の歴史の詳細な紹介 module_jquery

WBOY
WBOYオリジナル
2016-05-16 17:48:10925ブラウズ

データ キャッシュ システムは jQuery 1.2 で最初に導入されました。当時、そのイベント システムは DE マスターの addEvent.js をコピーしていましたが、addEvent の実装には欠陥があり、これにより、循環参照が発生する可能性がありました。 EventTarget はウィンドウ オブジェクトであり、地球規模の汚染を引き起こします。データ キャッシュ システムを使用すると、これら 2 つのリスクを回避することに加えて、さまざまなメソッドによって生成された中間変数を効果的に保存することもできます。これらの変数は別のモジュールのメソッドに役立ち、メソッド間の依存関係が分離されます。 jQuery の場合、そのイベントのクローン作成とその後のキューの実装さえも、キャッシュ システムから切り離すことはできません。

jQuery1.2 では、コア モジュールに 2 つの新しい静的メソッド、data とremoveData が追加されています。言うまでもなく、データは他の jQuery メソッドと同様に、読み取りと書き込みを組み合わせたものです。 jQuery のキャッシュ システムは、すべてのデータを $.cache に置き、キャッシュ システムを使用する必要がある各要素ノード、ドキュメント オブジェクト、およびウィンドウ オブジェクトに UUID を割り当てます。 UUID のプロパティ名はランダムなカスタム プロパティ「jQuery」(new Date()).getTime() で、値は 0 から増加する整数です。しかし、UUID は常にオブジェクトに付加されなければなりません。そのオブジェクトがウィンドウである場合、それはグローバル汚染ではないでしょうか。そのため、jQuery はそれがウィンドウ オブジェクトであると内部的に判断すると、それを windowData という空のオブジェクトにマッピングします。 UUID を追加します。 UUIDを使用すると、初めてキャッシュシステムにアクセスするときに、$.cacheオブジェクト内の空のオブジェクト(キャッシュ本体)を開いて、対象のオブジェクトに関連するものを配置します。これは銀行口座の開設に似ており、UUID の値が通帳になります。 RemoveData は、保存する必要がなくなったデータを削除します。最終的にデータが削除され、キーと値のペアがなく空のオブジェクトになった場合、jQuery はこのオブジェクトを $.cache から削除して移動します。ターゲットオブジェクトから。

コードをコピー コードは次のとおりです:

//jQuery1.2.3
var Expando = "jQuery" (new Date()).getTime(), uuid = 0, windowData = {};
jQuery.extend({
cache: {},
data: function) ( elem, name, data ) {
elem = elem == window ? windowData : elem;//ウィンドウオブジェクトの特殊処理
var id = elem[expando ];
if ( !id ) //そうでない場合は UUID が新しいものを作成します
id = elem[expando ] = uuid;
//$.cache にアカウントが開設されていない場合は、まずアカウントを開設します
if ( name && !jQuery.cache [ id ] )
jQuery.cache[ id ] = {};

// 3 番目のパラメータが未定義でない場合、書き込み操作になります
if ( data != unknown )
jQuery.cache[ id ][ name ] = data;
//パラメータが 1 つしかない場合はキャッシュ オブジェクトが返され、パラメータが 2 つある場合は対象のデータが返されます。
return name? .cache[ id ][ name ] : id;
},

removeData: function( elem, name ) {
elem = elem == windowData :
var id; = elem[expando ];
if ( name ) { //対象データを削除します
if ( jQuery.cache[ id ] ) {
delete jQuery.cache[ id ][ name ]; = "";

for ( name in jQuery.cache[ id ] )
break;
// キャッシュ本体が空でない場合は、名前が書き換えられます。書き換えられない場合、!name は true、
//このようにして、このメソッドが再度呼び出されますが、今回はキャッシュ本体を削除するために 1 つのパラメーターのみが渡されます。
if ( !name )
jQuery .removeData( elem );
}
} else {
//UUID を削除しますが、IE で要素に対して delete を使用するとエラーがスローされます
try {
delete elem[expando ];
} catch(e){
if ( elem.removeAttribute )
elem.removeAttribute(expando );
}// アカウントをキャンセル
delete jQuery.cache[ id ]; }
}
})


jQuery は、チェーン操作と集中操作を容易にするために、1.2.3 で同じ名前の 2 つのプロトタイプ メソッド data とremoveData を追加しました。そして、getData と setData のカスタム イベントのトリガー ロジックをデータに追加します。

1.3 では、データ キャッシュ システムは最終的に data.js モジュールに独立し (内部開発中に分割)、名前空間でのキューとデキュー、名前空間でのキューとデキューの 2 セットのメソッドが追加されました。プロトタイプ。キューの目的は明らかで、アニメーション モジュールにサービスを提供するために一連のデータをキャッシュすることです。デキューとは、一連のデータから 1 つの項目を削除することです。



コードをコピー コードは次のとおりです:

//jQuery1.3
jQuery.extend({
queue: function( elem, type, data) {
if ( elem ){
type = (type || "fx") "queue";
var q = jQuery.data( elem, type );
if ( !q || jQuery.isArray(data) )//配列が格納されていることを確認します
q = jQuery.data( elem, type, jQuery.makeArray(data) );
else if( data )//次に、このデータに何かを追加します
q.push( data ); }
return q;
},
デキュー: function( elem, type ){
var queue = jQuery.queue( elem, type ),
fn = queue.shift();//次に、1 つ削除します。初期の頃は、これはアニメーションを配置するためのコールバックでした。
// ただし、関数であるかどうかは判断されず、おそらく書き込まれません。これは内部使用のためのドキュメントです。
if( ! type || type === "fx" )
fn = queue[0];
if( fn !== unknown )
fn .call(elem);
}
)


fx モジュールの animate メソッドの呼び出し例:


コードをコピー コードは次のとおりです:
//それぞれ複数のアニメーションを並列処理し、キューは複数のアニメーションを次々に処理します
this [ optall.queue === false ? "each" : "queue " ](function(){ /*省略*/})

要素にカスタム属性を追加すると問題が発生します。この要素をコピーすると、この属性もコピーされるため、両方の要素が同じ UUID 値を持ち、データが正しく操作されなくなります。ノードをコピーする jQuery の初期の実装は非常に簡単です。要素の cloneNode メソッドがイベントをコピーしない場合は、cloneNode を使用します。それ以外の場合は、要素の externalHTML または親ノードの innerHTML を使用し、clean メソッドを使用して新しい要素を解析します。ただし、outerHTML と innerHTML には明示的な属性が記述されるため、正規表現を使用してクリアする必要があります。

コードをコピー コードは次のとおりです:
//jQuery1.3.2 core.js clone Method
var ret = this.map(function(){
if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
var html = this.outerHTML;
if ( !html ) {
var div = this.ownerDocument.createElement("div");
div.appendChild(this.cloneNode(true) );
html = div.innerHTML;

Return jQuery.clean([html.replace(/ jQueryd ="(?:d |null)"/g, "").replace(/^s*/, "")])[0 ];
} else
return this.cloneNode(true);
}); 外部リソースにインポートされたタグはエラーをスローする場合があります。古い IE の要素ノードは単なる COM ラッパーであるため、リソースを導入すると、そのリソースのインスタンスになり、厳密なアクセス制御があり、通常の JS オブジェクトのようにメンバーを自由に追加できません。そこで、jQuery はこれを完全に変更し、これら 3 つのタグのデータはキャッシュされなくなりました。 jQuery は、要素ノードのラベルを検出するために使用される noData というハッシュを作成しました。



コードをコピー
コードは次のとおりです: noData: { "embed": true, "object": true, "applet": true },
//Code Defense
if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
戻る ;
}


jQuery 1.4 では $.data も改良され、2 番目のパラメータをオブジェクトにして複数のデータを簡単に保存できるようになりました。 UUIDに対応するカスタム属性expandoも名前空間の下に配置されます。 queue メソッドと dequeue メソッドは新しいモジュールに取り除かれました。
jQuery1.43 では 3 つの改善が行われています。
1 つ目は、changeData カスタム メソッドを追加することです。しかし、この方法では売り上げはなく、プロダクトマネージャーのナルシストに過ぎません。
要素ノードがカスタム属性の追加をサポートしているかどうかを検出するロジックは、acceptData と呼ばれるメソッドに分割されています。 jQuery チームは、オブジェクト タグがフラッシュ リソースをロードするときにカスタム属性を追加できることを発見したため、この状況をそのままにしておくことにしました。 IE がフラッシュをロードするとき、その値は clsid:D27CDB6E-AE6D-11cf-96B8-444553540000 というオブジェクトに指定する必要があるため、data とremoveData の両方が使用されるため、検出ロジックは非常に複雑になります。は独立しています。効果的にビットを節約できます。
HTML5 は、「data-*」と呼ばれる新しいキャッシュ メカニズムを追加することで、カスタム属性を何気なく追加する人々の行動に対応しています。ユーザーが設定した属性が「data-」で始まる場合、要素ノードのデータセットオブジェクトに保存されます。このため、人々は HTML5 を使用してデータをキャッシュするか、jQuery のキャッシュ システムを使用してデータを保存することになるため、data メソッドは少し役に立たなくなります。そのため、jQuery はプロトタイプ上のデータを強化しました。ユーザーがこの要素ノードに初めてアクセスすると、「data-」で始まるすべてのカスタム属性が走査されます (古い IE を処理するために、データセットを走査することはできません)。直接)、それらを jQuery のキャッシュ本体に置きます。その後、ユーザーがデータを取得するときは、setAttribute を使用せずに、まずキャッシュ システムから「data-」カスタム属性にアクセスします。ただし、HTML5 のキャッシュ システムは非常に弱く、文字列しか保存できません (これはもちろん循環参照を考慮しているためです)。そのため、jQuery は文字列を「null」、「false」、「true」などのさまざまなデータ型に復元します。 、false、true 数値形式に準拠した文字列が「}」で始まる場合は数値に変換されます。
コードをコピー コードは次のとおりです:

//jQuery1.43 $.fn。 data
rbrace = /^(?:{.*}|[.*])$/;
if ( data === unknown && this.length ) {
data = jQuery.data( this [0] , key );
if ( data === unknown && this[0].nodeType === 1 ) {
data = this[0].getAttribute( "data-" key ); 🎜>
if ( typeof data === "string" ) {
try {
data = data === "true" ? true :
data === "false" ?
データ === "null" ? null :
!jQuery.isNaN( data ) ? parseFloat( data ) :
rbrace.test( data ) :
データ;
} catch( e) {}

} else {
data =
}
}

jQuery 1.5 では、3 つの改善も行われています。当時、jQueryはすでに1.42でPrototype.jsを破っており、マシュー効果でユーザー数は飛躍的に増加しました。その焦点は、パフォーマンスの向上とバグ修正段階への移行に変更されました (ユーザーが増えるほど、無料のテスターが増え、テスト範囲が広がります)。
expando を改善しました。元々は時間のカットオフに基づいていましたが、現在はバージョン番号と乱数を加えています。したがって、ユーザーは 1 つのページで複数のバージョンの jQuery を紹介することができます。
このデータがあるかどうかのロジックはhasDataメソッドに抽出され、HTML5の「data-*」属性もプライベートメソッドdataAttrに抽出されます。これらはすべて、ロジックをより明確に見せることを目的としています。 dataAttr は JSON.parse を使用します。これは、この JSON が JSON2.js によって導入された可能性があるためです。また、JSON2.js には非常に悪い点があります。つまり、一連のネイティブ型に toJSON メソッドが追加され、for in ループでエラーが発生します。空のオブジェクトかどうかを判断します。 jQuery は、処理のために isEmptyDataObject メソッドを作成することを強制されました。
jQuery のデータ キャッシュ システムは、当初はイベント システムを提供するために差別化され、その後、多くの内部モジュールのインフラストラクチャになりました。つまり、フレームワーク ユーザー向けの多くの変数 (システム データ) が内部的に保存されますが、ドキュメントに公開されると、ユーザーはビジネスで使用するデータ (ユーザー データ) を保存するためにもデータを使用するようになります。以前は、ユーザーの数が少なかったため、変数名の競合の可能性は比較的低かったです。また、jQuery は、__class__、__change__、またはサフィックスの追加など、これらのシステム データに対していくつかの珍しい名前を慎重に選択しました。 、苦情は受け付けられませんでした。 jQuery が世界クラスのフレームワークになったとき、ユーザー データ名がシステム データ名に置き換わり、イベント システムや他のモジュールがクラッシュすることがよくありました。 jQuery はキャッシュ本体の変換を開始し、それがオブジェクトであることが判明し、すべてのデータがそこにスローされました。これで、キー名としてランダムな jQuery.expando 値を使用して、このキャッシュ内にサブオブジェクトが開きます (システム データの場合)。ただし、前方互換性を保つために、イベントのシステム データは引き続きキャッシュに直接配置されます。システムデータの見分け方は非常に簡単で、値が true の場合は 4 番目のパラメータを直接追加します。 3 番目のパラメーターは、removeData を使用してシステム データを削除する場合にも提供されます。特にオペレーティング システム データ用に、新しい _data メソッドも作成されました。以下はキャッシュ本体の構造図です:
コードをコピー コードは次のとおりです:

var queue = {
jQuery14312343254:{/*システム データを配置します*/}
events: {/"イベント名とそれに対応するコールバック リストを配置します"/}
/*ユーザー データをここに配置します* /
}

jQuery 1.7 では、キャッシュ本体にシステム変数が配置されるようになりました。このため、キャッシュ本体が次のとおりであると判断した場合は、対応する改善を行う必要があります。次に、toJSON とデータをスキップする必要があります。新しい構造は次のとおりです:
コードをコピー コードは次のとおりです:

var キャッシュ= {
data :{/*ユーザー データを配置します*/}
/*システム データをここに配置します*/
}

jQuery1.8 では、かつて、deleteIds という配列が追加されていました。 UUID の再利用 しかし、それは短命でした。 UUID 値は 1.8 以降 jQuery.uuid を使用しなくなり、代わりに jQuery.guid によって増分生成されます。 jQuery 1.83以降の大きな改善点として、操作データの実装がプライベートメソッドとして抽出されるようになり、名前空間とプロトタイプ上のメソッドは単なるプロキシとなり、ユーザーデータを操作するためのdata、removeData、および操作用の_dataの2つのメソッドのグループに分けられました。オペレーティング システム データ、_removeData。現在、キャッシング システムだけでも大きなグループになります。
jQuery データ キャッシュの進化の歴史の詳細な紹介 module_jquery
最終的に、データ キャッシュは、ターゲット オブジェクトとキャッシュ本体の間に 1 対 1 の関係を確立し、キャッシュ本体上のデータを操作することです。複雑さは次の点に集中しています。前者。通常の JS オブジェクトの特定の属性を追加、削除、変更、確認することは決して難しいことではなく、ユーザーが特別なトリックを行うことはできません。ソフトウェア設計原則の観点から見ると、これは (KISS 原則と単一責任原則に沿って) 最良の結果でもあります。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。