30

jQuery スタイルの関数チェーンの原則を頭の中で真っ直ぐに理解しようとしています。これにより、次のことを意味します。

var e = f1('test').f2().f3();

1 つの例が機能するようになりましたが、別の例は機能しません。以下にそれらを掲載します。私は常に、何かがどのように機能するかの第一原則の基礎を学び、その上に構築できるようにしたいと考えています。これまで、連鎖がどのように機能するかについて大雑把で大まかな理解しかできておらず、インテリジェントにトラブルシューティングできないバグに遭遇しています。

私が知っていること:

  1. 関数は自分自身を返す必要があります。別名「これを返す」です。
  2. 連鎖可能な関数は、親関数、別名 jQuery に存在する必要があります。.css() は jQuery() のサブメソッドであるため、jQuery().css();
  3. 親関数は、それ自体またはそれ自体の新しいインスタンスを返す必要があります。

この例はうまくいきました:

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();
4

5 に答える 5

41

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();
変数 test に対して、gmap() コンストラクター (クラス) からすべてのプロパティとメソッドを「継承」する新しいオブジェクトを作成しました。上記のスニペットを実行すると、「追加」と「削除」のアラートが表示されます。

上記の例では、関数を別の関数またはオブジェクトでラップしない限り、「this」はウィンドウ オブジェクトを指します。

チェーンは最初は理解するのが難しく、少なくとも私にとってはそうでしたが、一度理解すると、それがいかに強力なツールであるかを実感しました。

于 2009-07-08T18:22:57.003 に答える
4

悲しいことに、直接の答えは「いいえ」でなければなりません。既存のメソッドをオーバーライドできたとしても (おそらく多くの UA ではオーバーライドできますが、IE ではオーバーライドできないと思われます)、厄介な名前変更に悩まされることになります:

HTMLElement.prototype.setAttribute = function(attr) { 
    HTMLElement.prototype.setAttribute(attr) //uh-oh;  
}

おそらく回避できる最善の方法は、別の名前を使用することです。

HTMLElement.prototype.setAttr = function(attr) {
    HTMLElement.prototype.setAttribute(attr);
    return this;
}
于 2012-06-10T01:43:36.377 に答える
1

関数を「書き直して」元のバージョンを使用できるようにするには、最初に元の関数を別の変数に割り当てる必要があります。オブジェクトの例を想定します。

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 *咳*

于 2012-06-10T01:51:43.607 に答える
-4

メソッドを var test = gmap().add(); として呼び出すだけです。

gmap は変数ではなく関数であるため

于 2014-11-19T12:27:31.690 に答える