JavaScript中的私有构造函数与静态成员

3

也许不太可能,但我很好奇。是否可以定义一个私有构造函数和一个公共工厂方法?

function MyParentClass() {}
MyParentClass.prototype.init = function() { ... }

function MyChildClass() {}
MyChildClass.prototype = new MyParentClass();
MyChildClass.prototype.init = function() {
    ...
    MyParentClass.prototype.init.apply(this);
    ...
}
MyChildClass.Create = function() {
    var instance = new MyChildClass();
    instance.init();
    return instance;
}

是否可能隐藏这两个构造函数,仅暴露Create()方法?

欢迎使用其他覆盖init()方法的方法。谢谢。

1个回答

8

我不确定您想要实现什么,但是下面是一个例子,其中MyClass将是一个单例,具有工厂方法create,允许创建MyClass实例。

//MyClass will be an object with a create method only
var MyClass = (function() {
    function MyClass() {
        this.initialized = false;
    }

    MyClass.prototype = {
        init: function () {
            this.initialized = true;
            return this;
        }
    };

    return {
        create: function () {
            return new MyClass().init();   
        }
    };

})();

var m = MyClass.create();
console.log(m);
console.log(m.constructor); //Will be Object because we replaced the whole prototype

然而,我不确定为什么你想要两个构造函数(initconstructor 本身)?你是因为对象创建过程过于复杂而试图将其抽象化吗?

我怀疑你只是想将 constructor 的逻辑移动到另一个函数中,因为你试图实现继承的方式。

你只是想避免在执行以下操作时调用构造函数逻辑吗?

MyChildClass.prototype = new MyParentClass();

如果是这种情况,使用 Object.create 可以解决您的问题(它不支持旧浏览器,但是有一个类似于“垫片”的东西——它支持您需要的特性,但并不支持 Object.create 的所有功能)。
function A(test) {
    this.test = test;
}

function B(test) {
    A.call(this, test); //call parent constructor
}
B.prototype = Object.create(A.prototype); //inherit from A

var b = new B('test');

console.log(b);
console.log(b instanceof A); //true

您还可以使用纯原型方法,而不需要与new关键字一起使用constructor函数。

var A = {
        init: function (test) {
            this.test = test;
            return this;
        }
    },
    B = Object.create(A),
    b;

    //override constructor function
    B.init = function (test) {
        return A.init.call(this, test);
    };

b = Object.create(B).init('test');

console.log(b);

我认为你关于继承的讨论并不是OP所问的,这只是噪音吗?也许我也没有理解问题。在我看来,第一部分完全回答了问题,私有构造函数和调用它的工厂方法。 - Ruan Mendes
@JuanMendes,我想提供尽可能多的细节,因为我怀疑OP提出这个问题是出于不良动机。此外,它还回答了“欢迎其他覆盖init()方法的方法”。 - plalx
你对于init函数的原因是正确的,那是因为我需要避免在构造函数中进行继承的初始化逻辑。但是,由于我可以使用Object.create来设置原型链,所以我可以将逻辑移回到构造函数中。谢谢! - Joe Flateau
2
是的,我应该更仔细地看代码实际在做什么,而不仅仅是字面上的问题。你非常好地简洁地描述了继承。我的错。 - Ruan Mendes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接