2

jquery コード ( https://github.com/jquery/jquery/blob/master/src/callbacks.js ) がメソッドのプロトタイプを使用しないのはなぜですか?

専門家がパフォーマンス上の理由からメソッドのプロトタイプを使用することを提案しているため、私はこれを求めています(関数は一度しか作成されないため)。

jquery コードからのコード スニペット、

self = {
            // Add a callback or a collection of callbacks to the list
            add: function() {
                if ( list ) {
                    // First, we save the current length
                    var start = list.length;
                    (function add( args ) {
                        jQuery.each( args, function( _, arg ) {
                            var type = jQuery.type( arg );
                            if ( type === "function" ) {
                                if ( !options.unique || !self.has( arg ) ) {
                                    list.push( arg );
                                }
                            } else if ( arg && arg.length && type !== "string" ) {
                                // Inspect recursively
                                add( arg );
                            }
                        });
                    })( arguments );
                    // Do we need to add the callbacks to the
                    // current firing batch?
                    if ( firing ) {
                        firingLength = list.length;
                    // With memory, if we're not firing then
                    // we should call right away
                    } else if ( memory ) {
                        firingStart = start;
                        fire( memory );
                    }
                }
                return this;
            },
            // Remove a callback from the list
            remove: function() {
                if ( list ) {
                    jQuery.each( arguments, function( _, arg ) {
                        var index;
                        while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
                            list.splice( index, 1 );
                            // Handle firing indexes
                            if ( firing ) {
                                if ( index <= firingLength ) {
                                    firingLength--;
                                }
                                if ( index <= firingIndex ) {
                                    firingIndex--;
                                }
                            }
                        }
                    });
                }
                return this;
            },

私の質問は、すべてのメソッドが、自己オブジェクトのプロトタイプになる別のオブジェクトの一部ではないのはなぜですか?

4

2 に答える 2

3

ここでこれらの特定の関数を使用すると、特定の変数 (たとえばlist) をクロージャに埋め込むことができますが、それらは非公開のままです。

標準的な方法でプロトタイプ ベースのオブジェクトを使用すると、これらのプロパティがパブリックになります。

選択するときの経験則は、変数の一貫性が必要なことかもしれません。変数を直接変更するとオブジェクトが無効な状態になる可能性がある場合は、より保護することが適切であると思われるかもしれません。ここで、たとえば、リストの長さを減らすと、インデックスが無効になる可能性があります。

于 2013-01-11T14:24:49.810 に答える
1

プロトタイプを使用する場合、オブジェクトの特権/パブリックメンバーにのみアクセスできます。

コードからわかるように、jQuery はオプションを public/privileged メンバーとして Callback オブジェクトに設定せず、Callback インスタンス内のオプションにアクセスするためにクロージャーを使用します。プロトタイプでメソッドを初期化すると、オプション オブジェクトにアクセスできなくなります。

別の例を次に示します。

プロトタイプの使用

function Callback(opt) {
    var options = opt;
}

Callback.prototype.execute = function () {
   console.log(typeof options);   //undefined
}

プロトタイプを使用せずに

function Callback(opt) {
    var options = opt;
    this.execute = function () {
       console.log(typeof options);   //object
    }
}

jQueryの考慮事項については確信が持てませんが、いくつかの仮定を次に示します。

  1. 私の意見では、コールバック オブジェクトによって内部で使用されるすべてのものへのパブリック アクセスを提供したくありません。

  2. 新品の使用。newAPIによって提供されるオブジェクトの初期化に使用するためにクライアントから要求するjQueryを見たことがありません。

新しいものは次の方法で回避できます。

function Callbacks() {
    if (this === window) {
        return new Callbacks();
    }
}

Callbacks.prototype.method = function () {
    //implementation
}

var c = Callbacks(); 

ただし、パフォーマンスのオーバーヘッドはほとんどありません。

  • これは、再帰呼び出しによるオーバーヘッドですreturn new Callbacks()
  • もう一つは の使用によるものnewです。jsperf では、通常、オブジェクト リテラルの方が高速であることがわかりますnew
  • そして最後のものは、プロトタイプ チェーンのトラバーサルからのものです。

    私が使用する場合:c.method();最初に JS インタープリターはc、呼び出しのためにのプロパティを調べますmethod。もちろん、そこには見つからないので、cのプロトタイプも検索する必要があります。

于 2013-01-11T14:37:15.063 に答える