2012-10-11 37 views
1

我有一些JavaScript使用揭示模塊模式,如下所示。它接受稍後調用的回調函數。我希望該回調函數能夠調用該類中定義的函數,但它不起作用。是否可以將Revealing模塊模式實例傳遞給回調函數?

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); 

我可以返工這個樣品放入顯露的原型模式和它的作品如預期,所以我的問題是我能得到這個工作使用RMP,或者是它只是一個這種模式的侷限性?

感謝, 羅傑

回答

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 
    }; 
}; 

然後,這既是一個實例方法,並通過返回的值可用。

但是對於這種簡單的事情(例如沒有私有變量),我會使用直接的原型(「原型模式」)。

順便說一句,如果你正在閱讀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); 
+0

謝謝!我認爲這是可能的 - 我只是沒有弄清楚語法。 – Roger

+0

第一個例子是有點誤導,因爲我在我的答案中描述的原因。你根本沒有得到一個真正的MyClass實例。但在這個例子中,也沒有關係。但這是一個很重要的細節。 –

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; 
}; 

但如果你喜歡馬修指出,這是在所有方面更快更簡單的不需要任何私人(你的例子揭示了一切,所以什麼都不依然私人)使用的原型爲基礎的方法。

相關問題