开发者

Inheritance of closure objects and overriding of methods

开发者 https://www.devze.com 2022-12-24 10:33 出处:网络
I need to extend a class, which is encapsulated in a closure. This base class is following: var PageController = (function(){

I need to extend a class, which is encapsulated in a closure. This base class is following:

var PageController = (function(){

    // private static variable
    var _current_view;

return function(request, new_view) {
    ...

    // priveleged public function, which has access to the _current_view 
    this.execute = function() {
        alert("PageController开发者_如何学运维::execute");
    }

}
})();

Inheritance is realised using the following function:

function extend(subClass, superClass){
var F = function(){
};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
StartController.cache = '';


if (superClass.prototype.constructor == Object.prototype.constructor) {
    superClass.prototype.constructor = superClass;
}
}

I subclass the PageController:

var StartController = function(request){
    // calling the constructor of the super class
    StartController.superclass.constructor.call(this, request, 'start-view');
}
// extending the objects
extend(StartController, PageController);

// overriding the PageController::execute
StartController.prototype.execute = function() {
alert('StartController::execute');
}

Inheritance is working. I can call every PageController's method from StartController's instance. However, method overriding doesn't work:

var startCont = new StartController();
startCont.execute();

alerts "PageController::execute". How should I override this method?


It doesn't work because StartController calls PageController which adds an execute property to your object, so the execute property of StartController.prototype is not used.

For your overriding to work, you have to either :

1) define PageController.prototype.execute as the execute method of PageController. It won't work because then the function doesn't have access to _current_view.

2) define StartController.execute in the object constructor :

var StartController = function(request){
    // calling the constructor of the super class
    StartController.superclass.constructor.call(this, request, 'start-view');
    // overriding the PageController::execute
    this.execute = function() {
      alert('StartController::execute');
    }
}
// extending the objects
extend(StartController, PageController);

edit:

So you want for StartController.execute to access _current_view, which is impossible as long as _current_view is part of a closure that StartController is not part of. You might have to proceed like this:

(function () {
  var _current_view;
  window.PageController = function(request, new_view) {
   ...
   this.execute = function() { ... }
  }

  window.StartController = function(request) {
    StartController.superclass.constructor.call(this, request, 'start-view');
    this.execute = function() { ... }
  }
  extend(StartController, PageController);

}()
var startCont = new StartController();
startCont.execute();

And if you want some kind of protected behavior, you might want to try this trick:

(function() {
  var token = {};

 window.Class1 = function() {
    this.protectedMethod = function(tok) {
      if(tok != token) return; // unauthorized
      ...
    }
  }

  window.Class2 = function() {
    new Class1().protectedMethod(token); // access granted
  }
})()

new Class1().protectedMethod(); // access denied

There's no such thing as a package in javascript, so your possibilities are limited. You can certainly not have any kind of privileges among functions/objects/constructors that are not part of the same script. None that I know of, at least. Except maybe querying a server for some kind of authorization.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号