1

JavaScriptモジュールとその書き方について学んでいます。パターンが正しいことを 100% 確信していないという問題に遭遇しました。後で私にとって簡単になるかもしれないコメントは素晴らしいですが、私の問題は、プロトタイプを正しく使用する方法がわからないことです。

モジュールを次のように使用します。

        var cm = CodeMirror.fromTextArea(document.getElementById("code"), {
            lineNumbers: true,
            matchBrackets: true,
            mode: "text/x-csharp"
        });
        var adapt = new $.codeMirrorSignalRAdapter(cm, $.connection.codeHub);

しかし、私の adapter.prototype hubChange では、this.silent は定義されていません。var adapter = function(cm,hub) がコンストラクターであり、プロトタイプ関数からプロパティ self.[cm,hub,silent] にアクセスする方法がわかりません。

(function ($, window) {
    "use strict";

    if (typeof ($) !== "function") {
        // no jQuery!
        throw new Error("CodeMirrorAdapter: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.");
    }
    if (typeof ($.signalR) !== "function") {
        throw new Error("CodeMirrorAdapter: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/signalr/hubs.");
    }

    var adapter = function (cm, hub) {
        var self = this;
        self.cm = cm;
        self.hub = hub;
        self.silent = false;

        cm.on("change", function (_, change) { self.onChange(change); });
        hub.client.Change = self.hubChange;

        return self;
    };

    adapter.fn = adapter.prototype = {
        init: function (cm, hub) {

        },
        onChange: function (change) {
            if (!this.silent) {
                this.hub.server.change(change)
                        .done(function () { })
                        .fail(function (ee) { alert(ee) });
            }
        },
        hubChange: function (change) {
            alert(this.silent);
            this.silent = true;
            this.cm.replaceRange(change.text[0], change.from);
            this.silent = false;
        },
    };


    $.codeMirrorSignalRAdapter = adapter;
}(window.jQuery, window));

このキーワードの問題以外に、モジュールの設計は多少問題ないように見えますか?

4

1 に答える 1

1

の値はthis、5 つの可能なオプションのいずれかです。詳細については、MDN のこの記事を参照してください: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/this

あなたの特定のケースでは、ハンドラーとしてhub.client.Change = self.hubChange;登録しています。hubChange問題は、ハンドラーが呼び出されたときthisに、正しいアダプター オブジェクトに設定されていることを確認するコードがないことです。

どうすればそれを保証できますか?

hub.client.Change = function () { self.hubChange.apply(self, arguments);};

applyここで詳細を読むことができますhttps://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply

私たちが行ったことは、cm.on("change")バインディングで行ったことと似ています。

コードへの想い

return self;あなたのコンストラクター関数は、それは必要ありませんで終わります。関数がコンストラクターとして、つまりnewキーワードを使用して呼び出されると、暗黙的に新しいインスタンスが返されます。関数がキーワードなしで呼び出されると、new関数が返すものは何でも返されますが、この場合は新しいインスタンスではありません。設定したものになりthisます。ほとんどの場合、それは返されwindowます。提案、その行を削除します。そうすれば、誤って new なしで呼び出すと、未定義に戻ります。

于 2012-12-01T22:06:34.543 に答える