问题描述
||
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();
当我向上分解原型链时,是否“重置” /从下一个函数调用的末尾开始?
是。
解决方法
我使用以下步骤在JavaScript中创建具有私有和公共范围的类:
创建仅具有公共成员的普通原型链
使用方法本身的布尔集将公共方法public或private成员标记为private。 (
function foo() {}; foo._private = true;
)
实例化“接口类”中的链
遍历链实例,在接口类上创建对其公共成员的引用
将这些引用重新绑定到链实例
这是一些代码:
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();
要查看输出,请签出此密码笔。
要看一下代码,以便使每个表达式的目的更加清楚,请检查一下此代码笔。
请注意,“ 5”已完全由“ 6”封装,但“ 7”仍然可以访问。
另外,请注意(new Interface()).A()
叫Subclass#B()
。