1

JavaScriptコードをクリーンアップしようとしているので、スパゲッティコードの記述をやめて、より全体的な構造にすることができます。簡単なフォームバリデーターを書いて自分のスキルをテストしたかったのです。しかし、私はすでに立ち往生しています。

これは私が現在持っているコードです:

(function($, window, undefined) {
    var Form = function($el) {
        this.$el = $el;
        this.fields = {};

        this.prototype.validate = function() {
            this.getFields();    
        }

        this.prototype.getFields = function() {
            console.log("getting fields");
        }

        return {
            validate: this.validate
        }
    };

    window.Form = Form;
})(jQuery, window);


$(function() {

    var form = new Form('#form-newsletter');
    form.validate();

});

これについてのいくつかの質問。

Form変数を自己実行関数でラップし、3つのパラメーターを渡しました。jQuery、window、およびundefinedを使用して、常に未定義であることを確認します。私はうそをつくつもりはありません、これは私がそれをすることを学んだ方法です、そして私はなぜ私がこのようにそれをするのか100%確信していません。これは悪い習慣ですか、それとも私はこれをどうにかして改善できますか?次に、Form変数をウィンドウにアタッチして公開します。

var内で、Formいくつかのプロパティを設定し(これは、どのように呼び出すのですか?)、いくつかのメソッドがあります。returnステートメントでvalidateメソッドのみを公開します。これで大丈夫ですか?

そして、行き詰まった部分。validate()フォームを検証するタスクを持つ初期化関数のようになりたいです。Validateは、getFields関数を呼び出してフォームフィールドを解析し、それらをフィールドオブジェクトに配置する必要があります。しかし、私はそれを機能させることができないようです。this.getFields()、、this.prototype.getFields()またはを呼び出すと機能しませんForm.getFields。これは、この関数のthis内部がFormオブジェクトとは異なるためですか(ここでは正しい表現ですか?)。this.self = thisフォーム関数の先頭に次のようなものを配置する必要がありますか?

また、これらのメソッドをプロトタイプにアタッチしても大丈夫かどうか疑問に思っています。これをしない理由はありますか?

私は学ぼうとしています。私がJavaScriptについて読んだほとんどの本は、基本、Dogつまりクラスから継承するクラスに焦点を当てていMammalます。しかし、私が知る限り、彼らはこのようなことで私を本当に助けてくれません。これらの概念をよりよく理解するのに役立つ本、チュートリアル、スクリーンキャストはありますか?

編集:

スクリプトを共通の名前空間にグループ化するとします。

var MyStuff = {};

MyStuff.Utilities = { // stuff };
MyStuff.Form = function() { // stuff };

ただし、これらを、、などの個別のファイルに入れたい場合は、どうすればよいmystuff-form.jsですmystuff-utilities.jsか?名前空間varをどこで宣言しますvar MyStuff = {}か?そして、それを行った後、フォームとユーティリティをそれに添付するだけですよね?MyStuff.jsそれだけでファイルを作ることはほとんどできませvar MyStuff = {}; window.MyStuff = MyStuffんね。

4

1 に答える 1

2

コンストラクターと、コンストラクターから作成できるオブジェクトを混同しています。プロトタイプの考え方は、コンストラクターのプロパティに関数を設定し、コンストラクター.prototypeを介して作成するすべてのオブジェクトからアクセスできるようにすることです。

コンストラクター内で、this作成されるオブジェクトを参照します。あなたの場合、そのようなオブジェクトのプロトタイプに何かを設定していますが、そのプロパティは存在しません。コンストラクターのプロパティを設定.prototypeするために、jQueryでは次のコマンドを使用して適切な構文を使用できます$.extend

// extend constructor's prototype with functions

$.extend(Form.prototype, {
    validate: function() {
        this.getFields();    
    },

    getFields: function() {
        console.log("getting fields");
    }
});

これで、どのオブジェクトにも.validate()使用可能な関数があります。

さらに、コンストラクターから新しいオブジェクトを返します。する必要はありません。それは継承/プロトタイプのアイデアさえも破壊します。

また、-あなたはコーディングthis.$el = $elしますが、あなたの場合はセレクター文字列を渡しているので、$($el)それをjQueryセットに変換したいと思います(そしておそらく引数の名前も変更します)。

最後に、無名関数はこれらすべての引数を渡す必要はありません。

  • jQuery -> $-これは、ページがjQuery.noConflict()モードの場合に便利です-$関数内としてjQueryにアクセスできます。
  • window -> window-実際には目的を果たしていません。window読み取り専用でさえあるので、変更されません。
  • undefined-最近のブラウザでは、これは読み取り専用であるため、渡す必要はありません。古いブラウザでは、a)渡さなかった場合、およびb)ページ上の一部のスクリプトが変更された場合にのみ競合が発生しますundefined。それはそれほど重要ではありませんが、もちろん、あなたのようにそれを渡すことは害はありません。

http://jsfiddle.net/4UNAp/を参照してください。

于 2012-10-04T16:17:51.403 に答える