Наследование объектов замыкания и переопределение методов - PullRequest
1 голос
/ 18 марта 2010

Мне нужно расширить класс, который заключен в замыкание. Этот базовый класс следующий:

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

}
})();

Наследование осуществляется с использованием следующей функции:

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

Я подкласс класса 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');
}

Наследование работает. Я могу вызвать каждый метод PageController из экземпляра StartController. Однако переопределение метода не работает:

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

оповещения "PageController :: execute". Как мне переопределить этот метод?

1 Ответ

2 голосов
/ 18 марта 2010

Это не работает, потому что StartController вызывает PageController, который добавляет свойство execute к вашему объекту, поэтому свойство execute StartController.prototype не используется.

Чтобы переопределить работу, вам нужно:

1) определить PageController.prototype.execute как execute метод PageController. Это не будет работать, потому что тогда функция не имеет доступа к _current_view.

2) определить StartController.execute в конструкторе объекта:

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

редактировать:

Итак, вы хотите, чтобы StartController.execute получил доступ к _current_view, что невозможно, если _current_view является частью замыкания, частью которого не является StartController. Возможно, вам придется действовать так:

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

И если вам нужно какое-то защищенное поведение, вы можете попробовать этот трюк:

(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

В javascript нет такой вещи, как пакет, поэтому ваши возможности ограничены. Конечно, вы не можете иметь никаких привилегий среди функций / объектов / конструкторов, которые не являются частью одного и того же сценария. По крайней мере, не знаю. За исключением, может быть, запроса к серверу для какой-либо авторизации.

...