私有子方法的原型

时间:2012-04-02 19:28:01

标签: javascript scope subclass extend

我的代码如下:

var baseClass = function() {
// CODE
    var subClass = function() {
        // MORE CODE
    }
}

向baseClass添加方法很好,我只使用

baseClass.prototype.newMethod = function () {
    // NEW CODE
}

我的问题是我应该如何向subClass添加方法?是简单地将它变成公共方法的唯一方法吗?

########编辑##############

好的,所以我重新安排了代码,所以subClass在baseClass之外。我传入了baseClass,因此subClass仍然可以访问baseClass实例的属性。

var baseClass = function() {
    var base = this;
    this.property_a = 1;
    this.property_b = 5;

    var sub = new subClass(base);
    // CODE
}

var subClass = function(parent) {
    var sub = this;
    this.property_c = 1;
    this.method_a = function() {
        return sub.property_c + parent.property_a;
    }
    // MORE CODE
}

这很好并且有效,但现在我有一个新问题,当我使用原型添加方法时:

subClass.prototype.method_b = function(){
    return sub.property_c + parent.property_b;
}

我收到错误,说父级未定义。

基本上我有一个相当简单的Web应用程序,它有两面,一个是查看面和一个编辑面。我构建了包含查看所需的所有内容的基类,并且我想在不同的文件中添加编辑所需的方法,因此只有当用户在编辑页面上时才会加载它们。

3 个答案:

答案 0 :(得分:1)

您必须在定义subClass的相同上下文中定义方法:

var baseClass = function() {
    // CODE
    var subClass = function() {
        // MORE CODE
    }
    subClass.prototype.newMethod = function () { ... }
}

如果无法做到这一点,那么您需要将subClass公开给适当的上下文,或者提供baseClass扩展subClass的机制。

答案 1 :(得分:1)

为什么要在基类中声明该子类?对我没有意义。

您可以在子范围内添加子类的原型。在你的代码中它将是

var baseClass = function() {
// CODE
    var subClass = function() {
        // MORE CODE
    }
    subClass.prototype = {
        ...
    }
}

但是我建议把它从基类构造函数中删除。如果由于某种原因你想要私有,请添加一个闭包:

(function(){

    baseClass = function() { // public
        // CODE
    }
    baseClass.prototype = {...};

    var subClass = function() { // private
        // MORE CODE
    }
    subClass.prototype = Object.create(baseClass.prototype);
    subClass.prototype.newMethod = function () { ... }
})()

编辑回答延伸的问题:

啊,subClass不从baseClass继承!我们曾预料到,否则将它放在构造函数中可能没问题。然后,可以将相同的原型添加到每个不同的子类构造函数中:

var subproto = {
    method_b: = function(){
        // manipulate "this"
    },
    ...
};
function baseClass() {
    // some code
    function sub() {
        // is a constructor for subs which belong to this specif base intance
        ...
    }
    sub.prototype = subproto; // the sub constructors of each base instance
                              // have the same prototype
    var x = new sub(),
        y = new sub(); // example usage of the sub constructor
}
baseClass.prototype = {...}

否则,如果你想要一个公共子构造函数(在函数baseClass之外),你可以将sub所属的基本实例作为构造函数的参数给出 - 正如你所做的那样。当然,sub(内部和外部方法)只能访问该基本实例的公共属性。

您在重新排列的代码中犯的错误是您的原型(“外部”)方法试图从子构造函数访问私有parent变量。正如你所说,“没有定义父级的错误”。

var subClass = function(parent) {
    var sub = this;
    this.parent = parent; // make it public
    this.property_c = 1;
    this.method_a = function() {
        return sub.property_c + parent.property_a;
    }
    // MORE CODE
}
subClass.prototype.method_b = function(){
    // prototype functions can only access public properties
    // i.e. privileged methods, public attributes and other prototype properties
    return this.property_c + this.parent.property_b;
}

答案 2 :(得分:0)

如果你真的想让子类保持私有,你可以在闭包中隐藏定义:

var BaseClass = (function() {
    function BaseClass() { ... };
    function SubClass() { ... };
    BaseClass.prototype.foo = function() { ... };
    SubClass.prototype.foo = function() { ... };
    return BaseClass;
})();

我个人发现这种封闭强制保护比它的价值更麻烦(例如,使调试更加困难)......但如果你想这样做,那就是你的意思。