【问题标题】:How good is this class pattern with private variables?这种带有私有变量的类模式有多好?
【发布时间】:2017-08-03 20:04:17
【问题描述】:

我在几篇文章中读到应该将类方法添加到 prototype 而不是写在函数体中,例如继承:

function MyClass() {
    var privateVar = 5;
}
MyClass.prototype.getVar = function() {
    return privateVar; // doesn't work!
}

但要访问变量,它们必须公开:

function MyClass() {
    //Some IDEs know this should be private because of the _underscore.
    this._privateVar = 5;
}
MyClass.prototype.getVar = function() {
    return this._privateVar; // works
}

但是,我有一个如何将班级成员设为私有的想法,但这需要更多的努力。这里我用一个转换字符的 Encryption 类来演示它:

;"use strict";

var EncryptionClass = function() {
    var priv = []; //The private namespaces of EncryptionClass instances
    
    function EncryptionClass() {
        //Create new private namespace for this instance:
        var p = {};
        this.privI = priv.push(p) - 1;
        
        //Private class member:
        p.password = (Math.random() * 200) | 0; // integer between 0 and 200
    }
    
    EncryptionClass.prototype.encrypt = function (str) {
        //Fetch private namespace
        var p = priv[this.privI];
        
        var res = "";
        for (var i = 0; i < str.length; i++)
            res += String.fromCharCode(str.charCodeAt(i) + p.password);
        
        return res;
    };
    
    return EncryptionClass;
}();

//Test:
var encryption = new EncryptionClass();
alert("Hello World\n" + encryption.encrypt("Hello World"));

这里,privI 变量是全局变量,但 priv 在闭包中,因此无法从外部访问私有命名空间。

我想知道您对这种模式的看法,以及它有哪些缺点/缺点。例如,我不确定这是否会导致 内存泄漏。

【问题讨论】:

  • 将成员添加到全局命名空间通常被认为是不优雅的。您可以改为从匿名函数返回 EncryptionClass
  • 这可能更适合代码审查。 codereview.stackexchange.com
  • 我会质疑为什么它首先需要如此私密。你从这个向后弯腰中究竟得到了什么?
  • 同意。我也看不出背部弯曲有什么好处
  • _privateVar 这样的命名约定通常足以“隐藏实现细节”; “隐藏”不一定要“物理上无法访问”,您根本不能编写触及他人隐私的代码。 “在某些情况下,这对数据安全很重要”对我来说听起来非常不自然。

标签: javascript class design-patterns prototype private


【解决方案1】:

我不确定这是否会导致内存泄漏。

确实如此。这将导致可怕的内存泄漏——不管EncryptionClass 实例何时被垃圾回收,那些私有命名空间对象永远不会。

这使得所有关于其他优点/缺点的讨论都是徒劳的。

【讨论】:

    猜你喜欢
    • 2018-03-04
    • 2014-11-10
    • 2018-05-08
    • 2023-04-05
    • 2014-09-20
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多