12

このテーマについて調査した後、jQueryコードを整理するためのパターンを何度も試してきました(たとえば、RebeccaMurphyがjQueryConferenceでこれについてプレゼンテーションを行いました)。

昨日、(明らかにした)モジュールパターンをチェックしました。結果は、私が思うYUI構文を少し思い出させます。

//global namespace MyNameSpace
if(typeof MNS=="undefined"||!MNS){var MNS={};}

//obfuscate module, just serving as a very simple example
MNS.obfuscate = function(){
    //function to create an email address from obfuscated '@'
    var email = function(){
        $('span.email').each(function(){
            var emailAddress = $(this).html().replace(' [ @ ] ','@');
            $(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>');

        });
    };    
    return {
        email: email
    };    
}();

//using the module when the dom's ready
jQuery(document).ready(function($){
    MNS.obfuscate.email();
});

結局、私はいくつかのモジュールを持っていました。一部の自然に含まれる「プライベートメンバー」は、この場合、このモジュール内の他の関数にとってのみ重要であり、したがってreturnステートメントに含まれなかった変数や関数を意味します。

コードの一部(たとえば、検索に関係するすべてのもの)をモジュールに結合することは理にかなっており、全体の構造が得られると思いました。

しかし、これを書いた後、私はJohn(Resig)の記事を読みました。そこでは、彼はモジュールパターンのパフォーマンスについても書いています。

「多数のプロトタイププロパティを使用して関数をインスタンス化することは、非常に高速です。モジュールパターンなどを完全に水から吹き飛ばします。したがって、頻繁にアクセスする(オブジェクトを返す)関数がある場合は、対話する人々の場合、オブジェクトプロパティをプロトタイプチェーンに含めてインスタンス化することは、あなたにとって有利です。コードでは、次のようになります。

// Very fast
function User(){}
    User.prototype = { /* Lots of properties ... */ };

// Very slow
function User(){
    return { /* Lots of properties */ };
}

(ジョンは、モジュールパターン「それ自体」に反対していないと述べています-ただあなたに知らせるために:)

それから、自分のコードで正しい方向に進んでいるかどうかはもうわかりませんでした。重要なのは、私は実際にはプライベートメンバーを必要とせず、また、当面は継承を必要としないと思います。今のところ私が欲しいのは、読み取り可能/保守可能なパターンだけです。これはある程度個人的な好みに帰着すると思いますが、(かなり深刻な)パフォーマンスの問題がある読み取り可能なコードになってしまうことはしたくありません。

私はJavaScriptの専門家ではないため、パフォーマンステストに関しては専門家ではありません。ですから、最初に、ジョンが言及したこと(「頻繁にアクセスされる関数(オブジェクトを返す)、人々に対話してもらいたい」、多くのプロパティなど)が私のコードにどの程度当てはまるのかはよくわかりません。私のコードが相互作用するドキュメントは、数百または数千の要素を含む巨大なものではありません。だから多分それはまったく問題ではありません。

しかし、私の頭に浮かんだことの1つは、単に持っているのではなく、

$('span.email').each(function(){
    var emailAddress = $(this).html().replace(' [ @ ] ','@');
    $(this).html('<a href="mailto:' + emailAddress + '">' + emailAddress + '</a>');
});

(domready関数内で)モジュールパターンを使用しているため、難読化と電子メールの2つの「追加」関数を作成します。追加機能の作成には時間がかかります。問題は、私の場合、それは測定可能でしょうか?

上記の例でクロージャが作成されているかどうかはわかりません(jQueryフォーラムの興味深い投稿で、次のように読んでいます:「内部関数がクロージャを作成するかどうかについて哲学的な議論があります。外部関数の可変オブジェクト...")ですが、実際のコードにはクロージャがありました。そして、そこに循環参照がなかったとは思いますが、これがどこまでガベージコレクションの高い(より)メモリ消費/問題につながる可能性があるのか​​わかりません。

私はこれについてのあなたの意見を本当に聞きたいです、そして多分あなたのコードのいくつかの例を見たいです。また、実行時間、メモリ、CPU使用率に関する情報を取得するためにどのツールを好みますか?

4

2 に答える 2

7

また、当面は継承は必要ないと思います

それはそう。これは、モジュールを名前空間として使用する場合には実際には当てはまりません。それはクラスインスタンスの類似物についてです。

完全に新しいオブジェクトからすべてのインスタンスを作成して作成するオブジェクトは、を使用し{name: member}て作成するオブジェクトよりも効率が低くなります。プロトタイプの場合、値が共有されるため、インスタンスの重量が軽くなります。new ClassClass.prototype.name= membermember

あなたの例MNSではシングルトンであるため、プロトタイプを介してメンバーを共有することによるメリットはありません。

上記の例でクロージャが作成されているかどうかはわかりません

はい、そうです。外部関数で変数が定義されていない場合でも、外部関数用に作成されたLexicalEnvironmentおよびscopeオブジェクトがあり、その中thisargumentsバインドされています。thisすべての内部関数は非表示にargumentsして独自のコピーを使用する必要があるため、巧妙なJSエンジンで最適化できる可能性がありますが、現在のJS実装のいずれかが実際にそれを行うかどうかはわかりません。

いずれにせよ、引数に重要なものを何も入れていないので、パフォーマンスの違いは検出できないはずです。単純なモジュールパターンの場合、害はないと思います。

また、実行時間、メモリ、CPU使用率に関する情報を取得するためにどのツールを好みますか?

開始する場所は、forループでコードを10000回実行し、どれだけ大きくなったかを確認するnew Date().getTime()ことです。これは、入手できる限り多くの異なるブラウザーで数回実行されます。

$(this).html()。replace('[@]'、'@');

(これは何をすることになっていますか?現時点では、スパンのHTMLを新しいものに読み取り、Stringの最初のインスタンスのみをで置き換え[ @ ]@新しい値を返しStringます。DOM内の既存のコンテンツは変更されません。)

于 2010-03-04T09:00:23.550 に答える
1

Javascriptはどれくらいありますか?私の経験では、ページに多くのJavascriptコードがあるサイトでは、パフォーマンスの問題は通常、実際に処理を行うコードに起因ます。一般的に、問題は、あまりにも多くのことをやろうとしたり、特定のことを本当にひどくやろうとしたりすることから生じます。例としては、「ライブ」のようなものを使用する代わりに、テーブル行(大きなテーブル)の要素にハンドラーをバインドするようなことをしようとします。

私のポイントは、モジュールや機能、または整理されたもののようなものが、ページに実際のパフォーマンスの問題を引き起こすことはほぼ確実ではないということです。このすべての問題に取り組む動機は何ですか?

于 2010-03-04T13:30:58.937 に答える