ホームページ  >  記事  >  ウェブフロントエンド  >  jQuery チェーン オペレーションを実装する方法とチェーン Operation_jquery を使用する理由

jQuery チェーン オペレーションを実装する方法とチェーン Operation_jquery を使用する理由

WBOY
WBOYオリジナル
2016-05-16 17:43:311602ブラウズ
2 つの質問
1. jQuery のチェーン操作はどのように実装されていますか?
2. チェーン操作を使用する理由
これら 2 つの質問のうち、どちらが答えやすいと思いますか?

チェーン操作
Baidu には原理に関する多くの情報があると思います。実際、チェーン操作はオブジェクトのメソッドを介して行われます。最後に、
戻ります。これは
オブジェクトを置き換えます。返された後も、オブジェクトはメソッドの呼び出しを継続できるため、チェーン操作を実行できます。次に、 は単に を実装します。
コードをコピーします コードは次のとおりです:

//JS クラスを定義します
function Demo() {
}
//そのプロトタイプを拡張します
Demo.prototype ={
setName:function (name) {
this.name = name;
return this;
},
getName:function () {
return this.name;
setAge:function (age)
this.age = age;
return this;
}
}
////Factory function
function D() {
return new Demo();
}
//チェーン可能な呼び出しを実装するには
D().setName("CJ").setAge(18).setName();

しかし...なぜ何を使う?

一般的な説明: コードの量を節約すると、コードがよりエレガントに見えます。
たとえば、チェーンがない場合は、次のようなコードを記述する必要がある場合があります:

コードをコピーコードは次のとおりです:
document.getElementById("ele").dosomething();
document.getElementById("ele").dootherthing();

このコードは 2 回呼び出されます。document.getElementById は DOM ツリーの要素を取得するために使用されます。これには大量のコストがかかり、2 行を記述する必要がありますが、chain メソッドは 1 行を記述するだけで済み、コードが節約されます。 .

しかし、キャッシュされた要素を使用することもできます。例:

コードをコピー コードは次のとおりです:
var ele = document.getElementById ("エレ" ; .
最悪の点は、すべてのオブジェクト メソッドがオブジェクト自体を返すことです。これは戻り値がないことを意味しており、これはどの環境にも適さない可能性があります。
例えば、非常に大きな整数 BigInteger (JavaScript の Number で保存するとオーバーフローする可能性のある整数) を作成したいのですが、その演算方法を拡張することで、連鎖演算を使用するのに適しているでしょうか?

たとえば、操作が 31415926535 * 4 - 271828182 の場合、チェーン スタイルで設計されている場合、メソッドは次のようになります。




コードをコピーします

これは中間結果が必要な場合はどうなるでしょうか。 ?おそらく次のように書かれるでしょう:



コードをコピー

コードは次のとおりです: var bigInteger = new BigInteger(" 31415926535"); var result1 = bigInteger.multiply(new BigInteger("4")).val(); var result2 = bigInteger.subtract("271828182") ).val(); console.log("result1 == " result1 ", result2 == " result2");
これはまったくエレガントとは思えません。チェーン操作を使用しないのと何ら変わりません。
では、元の BigInteger を変更できないという要件がある場合はどうなるでしょうか?まあ、チェーンオペレーションではこの要件を満たすことができないようです。

では、なぜチェーン操作を使用する必要があるのでしょうか?
より良い非同期エクスペリエンスのために
JavaScript はノンブロッキング言語であるため、ブロックしないわけではありませんが、ブロックできないため、イベントによって駆動され、一部の操作を非同期で完了する必要がありますプロセスをブロックする必要があります。

しかし、非同期プログラミングはクレイジーなものです...実行時に分離されるのは問題ではありませんが、コードを書くときにも分離されます...
一般的な非同期とは何ですか?プログラミングモデル?
コールバック関数
いわゆるコールバック関数とは、まずシステム内のどこかに関数を登録して、システムにこの関数の存在を知らせ、その後、 、誰かがイベントが発生したとき、この関数を呼び出してイベントに応答します。
コードをコピー コードは次のとおりです。

function f(num, callback){
if (numalert("低レベル関数の処理を呼び出します!");
alert("スコアを負にすることはできません。入力エラーです!");
}else if(num ==0){
alert("低レベル関数の処理を呼び出します!");
alert("学生は試験を受けていない可能性があります!");
}else{
alert( "高レベル関数の処理を呼び出します!");
setTimeout(function(){callback();}, 1000);
}
}

ここでのコールバックは、コールバック関数。コールバックは、num が負ではない数値の場合にのみ呼び出されることがわかります。
しかし、問題は、関数の内部を見ないと、コールバックがいつ、どのような状況で呼び出されるのかがわからないということです。コード間には特定の結合があり、ある程度の混乱が生じることになります。プロセス。

コールバック関数は非同期実装を実現するためのシンプルで展開しやすいメソッドですが、プログラミングの経験という点では十分ではありません。
イベント監視
つまり、イベント駆動型であり、実行順序はイベントの順序に依存します。
コードをコピー コードは次のとおりです。

function EventTarget(){
this .handlers = {};
}
EventTarget.prototype = {
constructor: EventTarget,
addHandler: function(type, handler){
this.handlers[type] = [];
},
fire: function(){
if(!event.target){
event.target = this;
}
if(this.handlers[event.type]配列のインスタンス] ){
var handlers = this.handlers[event.type];
for(var i = 0, len = handlers.length, i
handlers[i] ](イベント );
}
}
},
removeHandler: function(type, handler){
if(this.handlers[type]instanceof Array){
var ハンドラー= this.handlers[type];
for(var i = 0, le = handlers.length; i < len; i ){
if(handlers[i] === ハンドラー){
Break;
}
}
handlers.splice(i, 1);
}
}; 上記は「JavaScript」より高度なプログラミング」 カスタム イベントの実装。したがって、addHandler を通じてイベント処理関数をバインドし、fire を使用してイベントをトリガーし、removeHandler を使用してイベント処理関数を削除できます。

イベントを通じて切り離されていますが、プロセスの順序はさらに混乱します。

連鎖非同期

個人的に連鎖操作で最も評価できる点は、非同期プログラミング モデルの不明確な実行プロセスの問題を解決したことです。 jQuery の $(document).ready は、この概念を非常によく示しています。 DOMCotentLoaded は、DOM がロードされるまでは機能しませんが、jQuery の設計者はそれを「オブジェクトを選択して選択する」という操作に変えました。アイデア。 $ はドキュメント オブジェクトを選択し、その操作メソッドが準備完了です。このように、プロセスの問題は非常に明確であり、チェーン内の後の位置にあるメソッドが後で実行されます。


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

(function(){
var isReady=false; // onDOMReady メソッドが実行されたかどうかを判断します
var readyList= []; // 実行する必要のあるメソッドを一時的に格納しますこの配列は
var timer;//timer handle
ready=function(fn) {
if (isReady)
fn.call( document);
else
readyList.push ( function() { return fn.call(this);});
return this;
var onDOMReady=function(){
for(var i=0;ireadyList[i].apply(document);
}
readyList = null;
var bindingReady = function(evt){
if(isReady) ) return;
isReady=true;
onDOMReady.call(window)
document.removeEventListener("DOMContentLoaded",
); else if(document.attachEvent){
document.detachEvent("onreadystatechange", bindingReady);
if(window == window.top){
clearInterval(timer);
}
}
};
if(document.addEventListener){
document.addEventListener("DOMContentLoaded", bindingReady, false); {
document.attachEvent("onreadystatechange", function(){
if((/loaded|complete/).test(document.readyState))
bindReady();
}); 🎜 >if(window == window.top){
timer = setInterval(function(){
try{
isReady||document.documentElement.doScroll('left');//IE で使用doScroll を実行して、DOM がロードされているかどうかを確認できますか? 🎜>}
})();


上記のコードでは $(document).ready を使用できませんが、window.ready を使用する必要があります。

Promise

CommonJS の非同期プログラミング モデルもこの考え方を継承しており、各非同期タスクはコールバック関数を指定できる then メソッドを備えた Promise オブジェクトを返します。

したがって、
は次のように書くことができます:
f1().then(f2).then(f3);
このメソッドでは、あまり注意を払う必要はありません。非同期について理解する必要はありませんが、関数を使用してオブジェクトを選択し、操作する方法を知っていれば、非同期プログラミングを実行できます。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。