我正在学习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));
除了这个关键字的问题,模块设计看起来有点好吗?
答案 0 :(得分: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
。建议,删除该行。这样,如果你在没有新的情况下意外地调用它,你将得到未定义的。