【问题标题】:How do I use private functions/variables in the Javascript module pattern?如何在 Javascript 模块模式中使用私有函数/变量?
【发布时间】:2017-01-17 22:58:19
【问题描述】:

我正在阅读关于 Javascript 模块模式的 this 文章并遇到了一个 sn-p,它声称您可以跨模块文件保留私有变量/函数并相互访问它们:

var MODULE = (function (my) {
    var _private = my._private = my._private || {},
        _seal = my._seal = my._seal || function () {
            delete my._private;
            delete my._seal;
            delete my._unseal;
        },
        _unseal = my._unseal = my._unseal || function () {
            my._private = _private;
            my._seal = _seal;
            my._unseal = _unseal;
        };

        // permanent access to _private, _seal, and _unseal

    return my;
}(MODULE || {}));

我对如何实现这一点有点困惑,但我认为大部分困惑是由于不太了解它是如何工作的;它如何使其他已加载的脚本能够利用这些内部值?以及如何在这个“私有”空间中添加函数和变量?

我的最终目标是提供一种“抽象”函数变量,它必须在子模块中被覆盖,但仍需要在基本模块的文件中引用。诚然,我没有玩过这么多,但这主要是因为我试图了解实际实现的工作原理。

我正在考虑类似以下的内容,但它似乎不起作用,因为它无法访问内部函数:

    // Preserve state of private variables/functions across modules
    var _private = my._private = my._private || {},
        _seal = my._seal = my._seal || function () {
            delete my._private;
            delete my._seal;
            delete my._unseal;
        },
        _unseal = my._unseal = my._unseal || function () {
            my._private = _private;
            my._seal = _seal;
            my._unseal = _unseal;
        };

    my._private._unseal();

    my._private.bindEvents = function () {
        alert("This function should be re-declared in your sub-module.");
    };

    my._private._seal();

提前致谢。

【问题讨论】:

    标签: javascript design-patterns module


    【解决方案1】:

    我的最终目标是提供一种“抽象”函数变量 必须在子模块中被覆盖,但仍需要在 基本模块的文件。诚然,我没有玩过这么多,但是 这主要是因为我试图了解实际情况如何 实施工作。

    首先,前进。 JavaScript 不是传统的面向对象的编程语言。

    在 JavaScript 中,如果你想做一些事情,如果它被定义了,你可以这样做:

    // Look at entire prototype chain for a function
    if("doStuff" in obj) {
         obj.doStuff();
    }
    
    // Or just check if the own object has the whole function
    if(obj.hasOwnProperty("doStuff")) {
         obj.doStuff();
    }
    

    就 JavaScript 的私有或任何可见性而言,您在网上可能找到的一切都只是一个技巧,因为目前 JavaScript 没有访问修饰符。

    无论如何,您的示例将_seal_private 属性添加到通常称为exportsmy,并定义将属性添加到这些顶级属性的对象集是私有的或按约定密封的。所以,是的,这只是一个约定:不要从模块外部访问属于设置为 _private 的对象的一部分的此类属性...

    顺便说一句,我的两分钱是你应该避免这种情况并按原样使用 JavaScript 并处理没有访问修饰符的事实。

    与此同时,ECMA-Script 2015 及更高版本定义了一种新方法来声明属性名称是唯一标识符的属性,称为 symbols。如果您不拥有该符号,则无法访问整个属性:

    let sampleSymbol = Symbol("sample symbol");
    let sampleSymbol2 = Symbol("sample symbol 2");
    
    var obj = {
        // Defines the property with a symbol during object
        // declaration
        [sampleSymbol]: "hello world"
    };
    
    // Defines the property using regular property declaration syntax
    // once the object has been already built
    obj[sampleSymbol2] = "goodbye!";
    

    现在使用模块模式导出这个对象,其他模块将无法以简单的方式访问整个属性,这反过来又可以很好地模拟属性访问private em> 修饰符。

    最糟糕的是,您仍然可以使用 Object.getOwnPropertySymbols 函数获得给定的对象符号,但符号不是像 Array.prototype.forEach(...)for..inObject.keys(...)for..of 这样的迭代器的一部分,所以您应该去。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多