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

发布于 2024-11-16 23:08:50 字数 706 浏览 2 评论 0原文

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

当我解析原型链的更高层时,我是否在下一个函数调用的末尾“重置”/开始?
是的。

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

Situation 1:

(new sub()).D();

This doesn't work, as expected, since D and E are in different closures. I want to keep E private, since it should never be invoked directly (i.e. on an instance). I understand the reason for not being allowed to access E is to ensure encapsulation, but what can I do? My only two options appear to be to either make it privileged (which like I said, I am against since it will allow it to be called on an instance) or to manually copy it into each of my subclasses as a private method (which isn't much of a solution).

Situation 2:

(new sub()).A();

When I resolve higher up the prototype chain, do I "reset"/start at the end at the next function call?
Yes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

﹉夏雨初晴づ 2024-11-23 23:08:50

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

  1. 创建仅包含公共成员的普通原型链
  2. 使用方法本身的布尔值集将公共方法标记为公共或私有成员为私有。 ( vis. function foo() {}; foo._private = true; )
  3. 在“接口类”内实例化链
  4. 上创建对其公共成员的引用
  5. 迭代链实例,在接口类Rebind 这些对链实例的引用

下面是一些代码:

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代码笔

要查看稍微清理的代码以使每个表达式的目的更清晰,签出此代码笔

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

另请注意,(new Interface()).A() 调用 Subclass#B()

I have used the following steps to create a class with private and public scope in JavaScript:

  1. Create a normal prototype chain with only public members
  2. Either mark public methods public or private members as private using a boolean set on the method itself. ( vis. function foo() {}; foo._private = true; )
  3. Instantiate the chain inside an "interface class"
  4. Iterate over the chain instance, creating references to its public members on the interface class
  5. Rebind those references to the chain instance

Here's some code:

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

To see the output, checkout this code pen.

To see it with the code cleaned up a little bit to make the purpose of each expression a little clearer, checkout this code pen.

Note that function C() {} is fully encapsulated by function Interface() {} but (new Interface()).D() still has access to it.

Also, note that (new Interface()).A() calls Subclass#B().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文