对于类实例的私有成员,是否有更优雅的方法?

时间:2015-12-18 13:47:30

标签: javascript class instance private

我想为类创建设计标准以及创建类实例。结合来自多个网站的大量intel(例如来自stackoverflow),最终有一种方法可以获得相对最大的灵活性。我的目标就是拥有与更多定义的Java类相似的代码结构。

这是我到目前为止的工作代码片段(包括解释):

var MyClass = function (prop1)
{
    var _class = MyClass;
    var _proto = _class.prototype;

    // public member of constructed class-instance
    this.prop1 = prop1;

    // private static property as well as private member of class-instances
    // (see getter below!)
    var prop2 = this.prop1 * 10;
    // need to use this. instead of _proto because the property prop2 of
    // the class itself would be returned otherwise
    this.getProp2 = function ()
    {
        return prop2;
    }

    // 1 function for all instances of the class
    // reached by a fallback to the prototype
    _proto.protoAlert = function ()
    {
        // must call this.getProp2() instead of using prop2 directly
        // because it would use the private static member of the class
        // itself instead the one of the class-instance
        alert(this.prop1 + " " + this.getProp2());
    }
};

var c1 = new MyClass(1);
c1.protoAlert();
var c2 = new MyClass(2);
c2.protoAlert();
c1.protoAlert();

到目前为止效果很好。但是,要避免错误和脚本无法避免的错误行为,还有一些障碍。私有属性prop2存在于类实例和类实例中。这可能是一种意想不到的双重身份。此外,类实例的私有属性只能通过setter和getter-function正确访问。这不是最糟糕的事情,因为它强制执行访问私有变量的常用方法。缺点是:必须使用this.调用Setter和getter来实际引用类实例的prop2然后返回它。至于阶级继承 - 我还没有用我现在的标准来研究这个话题。希望它也能解决。

是否有一个更优雅的解决方案或至少一个不太容易出错的解决方案?

提前谢谢!

1 个答案:

答案 0 :(得分:2)

JavaScript并没有真正为私有属性提供实用模式。只要在构造函数中定义所有方法,您使用的模式才有效。您应该记住,这意味着每次创建类时,都会创建所有方法。

如果您考虑一下,私有变量不在程序中提供任何功能他们为程序员服务要记住,他应该和他应该做什么不要改变。因此,您可以简单地使用一些命名模式。我在其他人的代码中看到了很多这样的代码:

function MyClass() {
    // Private property
    this._helloWord = "Hello word.";
}
// From outside, accessed as `helloWord`, without underscore
Object.defineProperty(MyClass.prototype, "helloWord", {
    get: function() {console.log("helloWord getter");return this._helloWord;},
    set: function(value) {console.log("helloWord setter");return this._helloWord = value;},
};
MyClass.prototype.alertProp = function() {
    alert(this._helloWord);
}
// Accessing from the outside:
var instance = new MyClass();
alert(instance.helloWord); // will activate the getter function

大多数人会立即明白_underscored变量有一些特殊之处。您也可以通过这种方式使变量保持不变:

Object.defineProperty(MyClass.prototype, "helloWord", {
    value: "Hello world",
    writable: false // <----
};

详细了解Object.defineProperty。您还应该了解Javascript的结构与OOP语言略有不同。如果你试图推动其他语言&#39;它上面的图案会导致性能和结构问题。