我有一些使用Revealing Module Pattern的javascript,如下所示。它接受一个稍后调用的回调函数。我希望那个回调函数能够调用类中定义的函数,但它不起作用。
window.MyClass = function() {
var self = this,
start = function (callback) {
callback(self);
},
cancel = function() {
console.log('Cancel invoked');
};
return {
start: start,
cancel: cancel
};
};
var myCallbackFunction = function(instance) {
instance.cancel(); // Error: instance.cancel is not a function
};
var obj = new window.MyClass();
obj.start(myCallbackFunction);
我可以将这个样本重新修改为Revealing Prototype Pattern并且它按预期工作,所以我的问题是我可以使用RMP来解决这个问题,还是只是这种模式的限制?
谢谢, 罗杰
答案 0 :(得分:4)
window.MyClass = function() {
var self = this;
this.start = function (callback) {
callback(self);
};
this.cancel = function() {
console.log('Cancel invoked');
};
return {
start: this.start,
cancel: this.cancel
};
};
然后,它既是实例方法,也可以通过返回值获得。
但是对于这个简单的东西(例如没有私有变量),我会使用一个直接原型(" Prototype Pattern")。
顺便说一下,如果你正在阅读this series,你应该知道这些并不是真正的标准术语。
他还说,"虽然JavaScript不像C#或Java那样设计了类或面向对象编程的概念,但通过一些工作,您可以获得类似的结果。"实际上,JavaScript是为面向对象编程而设计的,但它是基于原型的。正如您所见,它还具有足够的灵活性以允许替代方案;在某些情况下,这些替代方案肯定更好。
你甚至不需要自己,因为你的对象一定会受到束缚。
所以:
window.MyClass = function(){};
window.MyClass.prototype = {
start: function (callback) {
callback(this);
},
cancel: function () {
console.log('Cancel invoked');
}
};
var myCallbackFunction = function(instance) {
instance.cancel();
};
var obj = new window.MyClass();
obj.start(myCallbackFunction);
答案 1 :(得分:1)
永远不要从构造函数返回对象。这是奇怪的JS怪癖之一。
您没有获得MyClass
的实例,而是获得了一个普通对象。当构造函数返回一个对象时,该对象将返回而不是将返回的实例。
// good!
function MyClass() {};
new MyClass().constructor // returns: function MyClass() {}
new MyClass().constructor == MyClass // true
// bad!
function MyClass() { return {a:123}; };
new MyClass().constructor // returns: function Object() { [native code] }
new MyClass().constructor == MyClass // false
简而言之,古典风格和揭示模块风格并不能很好地融合。
在您的情况下,任何分配给this
属性的函数都是向外部显示该函数。所以也许你想要这个。
window.MyClass = function() {
var self = this;
var start = function (callback) {
callback(self);
};
var cancel = function() {
somePrivateFn();
console.log('Cancel invoked');
};
var somePrivateFn = function() {
console.log('private function!');
};
this.start = start;
this.cancel = cancel;
};
但是如果你不需要任何私密的东西(你的例子揭示了一切,那么没有什么是私有的)使用像Matthew建议的基于原型的方法,这在所有方面都更快更简单。