我使用模块模式已经有一段时间了,但最近开始想将函数和属性混合到其中,以提高代码的重用。我已经阅读了一些关于这个主题的很好的资源,但是对于最好的方法仍然有点不确定。下面是一个模块:
var myModule = function () {
var privateConfigVar = "Private!";
//"constructor"
function module() {}
module.publicMethod = function () {
console.log('public');
}
function privateMethod1() {
console.log('private');
}
return module;
}下面是一个mixin对象:
var myMixin = function () {};
Mixin.prototype = {
mixinMethod1: function () {
console.log('mixin private 1');
},
mixinMethod2: function () {
console.log('mixin private 2');
}
};理想情况下,我希望混合一些来自其他对象的方法作为私有方法,而另一些方法作为公共方法,这样我就可以调用一些“扩展”函数,参数为" private "/" public“。所以,那
mixin(myModule, myMixin, "private");只需调用mixinMethod1()并具有正确的作用域,即可在myModule中使用myMixin方法,并且:
mixin(myModule, myMixin, "public");通过调用module.mixinMethod1()使myMixin方法在myModule中可用,并具有正确的作用域
我尝试过使用将属性从一个原型复制到另一个原型的方法,我尝试过使用下划线扩展方法将对象的属性从一个复制到另一个原型,以及在两者之间复制各种内容。我认为在这一点上我对作用域和原型有了一些转变,并且希望在使用模块模式时如何最好地做这样的混合。请注意,对象myMixin看起来是什么样子并不重要(无论是将函数添加到原型中,还是模块本身),我只是想找出一些方法来使其工作。
谢谢!
发布于 2014-02-12 23:00:01
with关键字在定义作用域时非常有用,但它也有一些缺点(顺便说一下,它在严格模式下是被禁止的)。
使用with关键字,您可以在模块体中定义一个私有变量privateScope,该变量将包含所有provate方法:
var myModule = function () {
var privateConfigVar = "Private!";
var privateScope = {};
//"constructor"
function module() {}
var proto = module.prototype;//avoids multiple attribute lookup
//Let's re-define you example' private method, but with a new strategy
privateScope['privateMethod1'] = function() {
console.log('private');
}
proto.publicMethod = function () {
with(privateScope){
//this call should work
privateMethod1();
}
console.log('public');
}
proto.publicMethod2=function(name,fn){
with(privateScope){
//this will be defined later by a Mixin
otherPrivateMethod();
}
console.log('public2');
}
proto.definePrivateFunction=function(name,fn){
privateScope[name] = fn;
}
return module;
}您的mixin将使用我们刚刚定义的definePrivateFunction将私有方法添加到私有作用域:
//An example mixin implementation
function Mixin(source,target,flag){
if(flag==="private"){
for(var currentMethodName in source){
target.definePrivateFunction(currentMethodName,source[currentMethod])
}
}else{
for(var currentMethodName in source){
target[currentMethodName]=source[currentMethod];
}
}
}下面的代码应该可以正常工作:
var test = myModule();
var testInstance = new test();
testInstance.publicMethod();// will call the private method defined internally
Mixin({
otherPrivateMethod:function(){
console.log("other Prvate Method called")
}
},test.prototype,"private");
testInstance.publicMethod2();// will call the private method defined by the mixinhttps://stackoverflow.com/questions/17631517
复制相似问题