从JavaScript中的子类调用baseclass中的私有方法的解决方法

时间:2011-06-23 11:34:21

标签: javascript oop class encapsulation prototype-programming

base = function () {
  this.A = function () {
    this.B();
  }
  this.B = function () {} // ABSTRACT!
  var E = function () {
    alert('I am E');
  }
}

sub = function () {
  this.B = function () {
    alert('I am B');
  }
  this.D = function () {
    E();
  }
}

sub.prototype = new base();

情况1:

(new sub()).D();

这不符合预期,因为D和E处于不同的闭包中。我想保持E私有,因为它永远不应该直接调用(即在实例上)。我理解不允许访问E的原因是为了确保封装,但我该怎么办?我唯一的两个选择似乎是让它成为特权(就像我说的那样,我反对,因为它允许在一个实例上调用它)或者手动将它复制到我的每个子类中作为私人方法(这不是一个解决方案)。

情况2:

(new sub()).A();

当我解决原型链的更高位置时,我是否会在下一次函数调用时“重置”/启动?

1 个答案:

答案 0 :(得分:0)

我已使用以下步骤在JavaScript中创建具有私有和公共范围的类:

  1. 创建仅包含公共成员的普通原型链
  2. 使用方法本身的布尔值将公共方法public或private成员标记为private。 (见function foo() {}; foo._private = true;
  3. 在“接口类”
  4. 中实例化链
  5. 遍历链实例,在接口类
  6. 上创建对其公共成员的引用
  7. 重新绑定对链实例的引用
  8. 以下是一些代码:

    function BaseClass() {
      this.A = function A() {
        this.B();
      }
      this.B = function B() {}
      this.C = function C() {
        console.log('I am C');
      }
      this.C._private = true;
    }
    
    function Subclass() {
      this.D = function D() {
        this.C();
      }
      this.B = function B() {
        console.log('I am B');
      }
    }
    Subclass.prototype = new BaseClass();
    
    function Interface() {
    
      var classScope = new Subclass();
      for ( var property in classScope ) {
        if ( !classScope[property]._private ) {
          this[property] = classScope[property].bind(classScope);
        }
      }
    }
    
    var classInstance = new Interface();
    console.log(classInstance);
    classInstance.A();
    classInstance.B();
    classInstance.D();
    

    要查看输出,请结帐this code pen

    要查看代码,请稍微清理一下,以使每个表达的目的更加清晰,checkout this code pen

    请注意,function C() {}完全封装了function Interface() {},但(new Interface()).D()仍然可以访问它。

    另请注意(new Interface()).A()来电Subclass#B()