Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 对私有成员使用闭包或下划线约定_Javascript_Design Patterns - Fatal编程技术网

Javascript 对私有成员使用闭包或下划线约定

Javascript 对私有成员使用闭包或下划线约定,javascript,design-patterns,Javascript,Design Patterns,道格拉斯·克罗克福德和其他许多人如下: function Container(param) { function dec() { if (secret > 0) { secret -= 1; return true; } else { return false; } } this.member = param; var secret =

道格拉斯·克罗克福德和其他许多人如下:

function Container(param) {

    function dec() {
        if (secret > 0) {
            secret -= 1;
            return true;
        } else {
            return false;
        }
    }

    this.member = param;
    var secret = 3;
    var that = this;
}
这样做的好处是在构造函数之外无法访问这些成员,但缺点是在原型中不可能使用私有成员。因此,您最终会将所有使用私有成员的内容都放在构造函数中,这对于内存来说是不好的

其他一些人建议在命名私有成员时使用下划线:

function Container(param) {
    this.member = param;
    this._secret = 3;
}

Container.prototype.dec = function {
    if (this.secret > 0) {
        this.secret -= 1;
        return true;
    } else {
        return false;
    }
}
这样做的缺点是,这些成员很容易公开接触,唯一阻止人们的是公约

我的问题是:

  • 你什么时候决定用一个而不是另一个
  • 一种方式比另一种更普遍吗
  • 有哪些著名的库使用这些方法之一
  • 有比这两种更好的方法吗
    正如您已经概述的,这两种方法之间存在权衡。所以,使用哪一个完全取决于用例的细节,没有答案不考虑实际的用例。您可以通过以下几种方式约束决策:

    如果您正在制作成千上万个这样的对象,那么不使用原型增加的内存使用量可能是有意义的,您可能希望牺牲真正的隐私,以便管理内存使用量并使用没有真正隐私的原型版本。如果您没有制作大量的对象,或者没有在非常紧凑的内存占用空间中运行,那么内存使用的差异就无关紧要了

    Crockford提出了这样一个观点:如今,内存问题很少是一个真正的问题。但是,我认为这只是一个一般性的陈述,你必须评估你的特殊情况,才能知道这是不是真的

    如果隐私是最重要的,并且您绝对不希望外部人员干扰内部私有变量(可能这甚至是API的安全问题或可靠性问题),那么请务必选择提供真正隐私的关闭选项

    你什么时候决定用一个而不是另一个

    这取决于您最想优化的内容,最佳选择是特定于用例的

    一种方式比另一种更普遍吗

    这取决于您最想优化的内容,最佳选择是特定于用例的

    有哪些著名的库使用这些方法之一

    jQuery混合使用了这些方法。它有一些以下划线开头的“非公共”属性。而且,它使用了一些真正私有的闭包变量,尽管通常仅适用于只有一个或少量的对象,有时仅适用于模块级全局变量。随着时间的推移,在我看来jQuery已经将它的一些
    \u priv
    属性切换到了更受保护的闭包变量,但每个属性仍然有一些

    这可能是因为jQuery试图优化jQuery对象本身的内存使用,因此不希望为方法创建额外的闭包或使用额外的内存。但是,对于它使用的其他类型的对象,在没有那么多的情况下,它可以更容易地为真正的隐私提供额外的内存使用

    有比这两种更好的方法吗

    如果您有可用的weakmap,那么还有另一个选项。闭包是我见过的在更老的浏览器上实现真正隐私的最好方案。表示非公开的唯一其他方法是按惯例,最前面的下划线是更常见的惯例


    根据Felix的建议,下面是
    weakMap
    选项的工作原理

    var MyClass = (function () {
        var data = new WeakMap();
        return class MyClass {
            constructor() {
                var secretData = {
                    foo: 42
                };
                data.set(this, secretData);
            }
            // normal prototyped method can get access to the private data
            doSomethingWithSecret() {
                return data.get(this).foo * 2;
            }
        };
    }());
    
    每个类定义有一个
    WeakMap
    对象。在对象的构造函数中,使用
    this
    作为键将对象存储在weakMap中。由于您需要
    this
    和访问
    weakMap
    才能访问私有数据,因此只有在私有闭包中定义的方法才能访问weakMap,但与Crockford方法不同,您可以在此闭包中使用.prototype方法。这将为每个类创建一个闭包,为每个类创建一个
    WeakMap
    对象,因此这两个对象都不是每个实例


    因为这里的一切似乎都是某种折衷,所以每当您想要获取或设置WeakMap的数据时,与其他两种方法中的任何一种相比,性能都会受到一些影响。性能影响的程度完全取决于weakMap的实现,如果性能是最重要的,则必须对其进行衡量,但它可能更像是一个查找过程,而不仅仅是一个简单的属性查找,而且可能没有经过优化,因为它也是一个相对较新的功能。

    1。通常情况下,好处大于坏处。2.这是第三条。这是离题的。4.也许是使用了软弱的标志或符号。@FelixKling感谢你的讽刺,这绝对没有任何价值。我不是在讽刺。使用这两种方法的好处在很大程度上取决于这些类的具体用例(我们不知道)。@FelixKling我不是故意粗鲁,但“当好处大于坏处时”不是答案。你认为什么时候利大于弊?对于第二个问题,可以量化的东西怎么可能是主观的呢?谢谢你接下来的评论。“你认为什么时候利大于弊?”当人们很有可能访问“私人成员”和/或这些成员包含计算数据时,你必须阻止人们访问这些数据。如果您只是想防止人们弄乱组件的内部状态,我就不麻烦了。如果他们想的话,就让他们射自己的脚吧。防止这种情况的发生并不值得付出额外的复杂性。然而,这是我的观点。WeakMap也可用于存储私有实例数据,但不包括cou