私は、jQueryスタイルの関数チェーンを頭の中でまっすぐに行うという原則を理解しようとしています。これはつまり:
var e = f1('test').f2().f3();
私は1つの例が機能するようになりましたが、別の例は機能しません。以下に投稿します。私は常に、何かがどのように機能するかについての第一原理の基礎を学び、その上に構築できるようにしたいと思っています。これまで、チェーンがどのように機能するかについては大雑把で大まかな理解しかなく、インテリジェントにトラブルシューティングできないバグに遭遇しています。
私が知っていること:
この例は機能しました:
var one = function(num){
this.oldnum = num;
this.add = function(){
this.oldnum++;
return this;
}
if(this instanceof one){
return this.one;
}else{
return new one(num);
}
}
var test = one(1).add().add();
しかし、これはそうではありません:
var gmap = function(){
this.add = function(){
alert('add');
return this;
}
if(this instanceof gmap) {
return this.gmap;
} else{
return new gmap();
}
}
var test = gmap.add();
JavaScriptでは、関数はファーストクラスのオブジェクトです。関数を定義するとき、それはその関数オブジェクトのコンストラクターです。言い換えると:
var gmap = function() {
this.add = function() {
alert('add');
return this;
}
this.del = function() {
alert('delete');
return this;
}
if (this instanceof gmap) {
return this.gmap;
} else {
return new gmap();
}
}
var test = new gmap();
test.add().del();
を割り当てることによって
新しいgmap();
上記の例では、関数を別の関数またはオブジェクトでラップしない限り、「this」はウィンドウオブジェクトを指します。
連鎖は最初は理解しづらいですが、少なくとも私にとってはそうだったのですが、理解してみると、ツールの威力を実感しました。
悲しいことに、直接の答えは「いいえ」でなければなりません。既存のメソッドをオーバーライドできる場合でも(おそらく多くのUAで可能ですが、IEではできないと思われます)、厄介な名前変更に悩まされることになります。
HTMLElement.prototype.setAttribute = function(attr) {
HTMLElement.prototype.setAttribute(attr) //uh-oh;
}
おそらく回避できる最善の方法は、別の名前を使用することです。
HTMLElement.prototype.setAttr = function(attr) {
HTMLElement.prototype.setAttribute(attr);
return this;
}
関数を「書き換え」ても元のバージョンを使用できるようにするには、最初に元の関数を別の変数に割り当てる必要があります。サンプルオブジェクトを想定します。
function MyObject() { };
MyObject.prototype.func1 = function(a, b) { };
書き直すにはfunc1
連鎖性のために、これを行います:
MyObject.prototype.std_func1 = MyObject.prototype.func1;
MyObject.prototype.func1 = function(a, b) {
this.std_func1(a, b);
return this;
};
これが 実例 です。連鎖性が必要だと思われるすべての標準オブジェクトにこの手法を採用する必要があります。
このすべての作業を行うときまでに、チェーン機能がすでに組み込まれているライブラリを使用するなど、実行しようとしていることを達成するためのより良い方法があることに気付くかもしれません。 *咳*jQuery*咳*
まず、私が自分の言葉でこれを説明していることを述べさせてください。
メソッドチェーンは、別の関数/メソッドによって返されるオブジェクトのメソッドを呼び出すこととほぼ同じです。たとえば(jqueryを使用):
$('#demo');
このjquery関数は、jqueryオブジェクトを選択してIDデモのDOM要素を返します。要素がテキストノード(要素)の場合、返されたオブジェクトのメソッドをチェーンできます。例えば:
$('#demo').text('Some Text');
したがって、関数/メソッドがオブジェクトを返す限り、返されたオブジェクトのメソッドを元のステートメントにチェーンできます。
後者が機能しない理由については、キーワードthis
がいつどこで使用されるかに注意してください。コンテキストの問題である可能性があります。 this
を呼び出すときは、this
がウィンドウオブジェクト/グローバルスコープではなく、その関数オブジェクト自体を参照していることを確認してください。
お役に立てば幸いです。