在javascript中原型化闭包方法

在javascript中原型化闭包方法,javascript,oop,interface,closures,Javascript,Oop,Interface,Closures,我是javascript新手,我的问题可能非常愚蠢。我无法得到这方面的正确参考 我正在尝试用javascript编写一个控制器对象。这里的想法是让它成为一个接口对象,任何人都可以从它的原型中继承并重写它们的方法 我只想向对象公开一个方法“process()”,这个方法将调用所有剩余的方法和属性。我试图通过使用闭包使所有其他方法和属性私有来实现这一点。这是我的代码的示例片段 var ViewController = function() { var _viewName = null;

我是javascript新手,我的问题可能非常愚蠢。我无法得到这方面的正确参考

我正在尝试用javascript编写一个控制器对象。这里的想法是让它成为一个接口对象,任何人都可以从它的原型中继承并重写它们的方法

我只想向对象公开一个方法“process()”,这个方法将调用所有剩余的方法和属性。我试图通过使用闭包使所有其他方法和属性私有来实现这一点。这是我的代码的示例片段

var ViewController = function() {

    var _viewName = null;


  var loadView = function(viewName) {

    console.log("now loading view : "+viewName+ " ...");
  };

    return {
        process : function(viewName){
            _viewName = viewName;
            loadView(_viewName);
        }
    };

};


var vController = ViewController();
vController.process("alphaView");
现在这个工作非常好。但是,如果我想使用prototype覆盖PreProcess、loadView、initView和PostProcess方法,它就不起作用了。我尝试使用Object.create-like重写

var vController2 = Object.create(ViewController, {

  LoadView : function(viewName) {
    //some custom implementation
  },
  //and so forth
});
如果我改变我的实现来定义使用原型以外的方法,也不会起作用。像

 var ViewController = function() {

      var _viewName = null;

      return {
        process : function(viewName){
          _viewName = viewName;
          loadView(_viewName);
        }
      };

    };

    ViewController.prototype.loadView = function(viewName) {

        console.log("now loading view : "+viewName+ " ...");
    };
我的问题的要点是我想要 (a) 控制器的接口对象,用户可以在其中重写一个基本方法(LoadView,) (b) 所有这些成员都是控制器对象的私有成员,可以通过“Process()”方法进行访问

请告知


编辑:编辑代码使其变得简单。

将您希望人们能够覆盖的方法放在原型上,这样它们才是真正的方法,并被
process()
称为真正的方法。然后,一旦创建了这种类型的对象,就可以为任何方法创建新的覆盖定义,
process()
将自动调用它们,而不是原始方法。一种方法是:

function ViewController() {
}

ViewController.prototype = {
    loadView: function(viewName) {
        console.log("now loading view : "+viewName+ " ...");
    },
    preProcess: function(viewName) {
        console.log("now Pre Processing view : "+viewName+ " ...");
    },
    // other methods here ...
    process: function(viewNmae) {
        this.viewName = viewName;
        console.log(_viewName);
        this.preProcess(_viewName);
        this.loadView(_viewName);
        this.initView(_viewName);
        this.postProcess(_viewName);
    }
}

var controller = new ViewController();
controller.loadView = function(viewName) {
    // override function for loadView
}
controller.process(viewName);

如果您真的想禁止调用覆盖方法,那么您就必须放弃使用javascript的内置原型机制(因为它是公共的,任何方法都可以被调用)。因此,您可以使用自己的方案,只需添加新的公共方法来设置覆盖函数。在现有代码中,更改以下内容:

return {
    process : function(viewName){
        _viewName = viewName;
        loadView(_viewName);
    }
};
为此:

return {
    process : function(viewName){
        _viewName = viewName;
        loadView(_viewName);
    },
    setLoadViewFn: function(fn) {
        loadView = fn;
    }
    // add other override setting functions here
};


// create controller object
var controller = new ViewController();
// set override function for loadView
controller.setLoadViewFn(function(viewName) {
    // override function for loadView
});
controller.process(viewName);

请将您的代码简化为您尝试执行的操作的最小(或至少更短)示例。如果您希望从实现外部重写方法,请不要将它们设置为私有的本地函数。而是将它们添加到实际的对象原型中。只有一个实际的方法
process()
,不清楚您真正想要解决的问题是什么。这听起来像是在回避普通的javascript功能。我想要的是,开发人员可以实际创建ViewController的继承对象,并实现自己的LoadView方法。例如,应用程序可以有多个控制器,如controller1、controller2等,每个控制器在其LoadView上不执行不同的操作。但无论何时何地实例化的控制器对象只能调用process(),即调用LoadView的唯一方法是通过process()。我可能完全弄错了,这就是我需要建议的原因。我认为这里混淆的主要原因(在jfriend00所说的之后)是,如果您从使用
new
调用的构造函数中返回一个对象,它会丢弃构造函数自己的实例,以支持返回的对象,而返回的对象(不一定/默认)继承与构造函数相同的原型。您可能会发现有帮助。@curioussam-好的,现在我更好地理解了您的意图,我在回答中添加了另一个选项。因此,使用闭包将这些成员设置为“私有”似乎不是一个好选项。这对我来说是一个范例转变,因为我来自一种经典的OO语言。如果你想使用javascript的内置对象/原型特性,这不是一个好的选择。您可以使用您的方案,但必须公开用于设置覆盖函数的方法,并将这些方法存储在您自己的私有实例数据中。这是我所知道的唯一允许设置方法的方法,但无法在
process()
@curioussam之外调用它们-既然您已经更好地描述了您要做的事情,我已经使用您现有的代码隐私机制添加了另一个选项。这很有意义,我可以在这里看到一些抽象和封装!这可能有用。谢谢:)这种方法似乎不起作用,因为它返回了一个错误,“SyntaxError:需要一个标识符,但找到了“function”