在javascript中原型化一个闭包方法

时间:2013-03-17 22:25:44

标签: javascript oop interface closures

我是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");

现在这完全没问题。但是如果我想使用原型覆盖方法PreProcess,loadView,initView和PostProcess,它就不起作用了。我尝试覆盖使用Object.create,如

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()”方法访问

请指教!

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

1 个答案:

答案 0 :(得分:1)

将您希望人们能够覆盖的方法放在原型上,这样它们就是真正的方法,并被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);