【问题标题】:Javascript Module Pattern Memory Footprint and PerformanceJavascript 模块模式内存占用和性能
【发布时间】:2012-03-14 03:51:56
【问题描述】:

我正在使用 Javascript 模块模式来尝试实现类似 C# 枚举的功能。我目前正在考虑两种方法来实现此功能,但我不了解一种方法与另一种方法相比的所有好处或优势。

这里是实现 1:

var MyApp = (function (app) {

    // Private Variable
    var enums = {
        ActionStatus: {
            New: 1,
            Open: 2,
            Closed: 3
        }
    };

    // Public Method
    app.getEnum = function (path) {
        var value = enums;            
        var properties = path.split('.');
        for (var i = 0, len = properties.length; i < len; ++i) {
            value = value[properties[i]];
        }
        return value;
    };

    return app;

})(MyApp || {});

// Example usage
var status = MyApp.getEnum("ActionStatus.Open");

现在实现 2:

var MyApp = (function (app) {

    // Public Property
    app.Enums = {
        ActionStatus: {
            New: 1,
            Open: 2,
            Closed: 3
        }
    };

    return app;

})(MyApp || {});

// Example usage
var status = MyApp.Enums.ActionStatus.Open;

主要区别在于使用“私有”变量与“公共”属性来存储枚举。我认为实现 1 会慢一些,但我不确定将枚举保持为“私有”是否会减少内存使用量。谁能解释两者在内存占用和性能方面的差异(如果有的话)?任何其他建议/建议表示赞赏。

【问题讨论】:

    标签: javascript performance optimization memory


    【解决方案1】:

    ...但我不确定将枚举保持为“私有”是否会减少内存使用量

    相反,如果有的话:你仍然必须有枚举对象,并且你必须有一个函数来访问它。

    在速度方面,我不会担心。添加的函数调用不会产生任何真正的区别(我looked into it 担心使用新的forEach 等,甚至在具有大量慢JS引擎的IE6上,它只是没有'没关系)。

    几年后,您可能会拥有两全其美:只读枚举,这要归功于 ECMAScript5 的 Object.defineProperties 功能:

    var Enums = Object.defineProperties({}, {
        ActionStatus: {
            value: Object.defineProperties({}, {
                New:    {value: 1},
                Open:   {value: 2},
                Closed: {value: 3}
            })
        }
    });
    
    // Usage
    var n = Enums.ActionStatus.New; // 1
    

    默认情况下,使用defineProperties 创建的属性是只读的

    事实上,如果你添加一个 ES5“shim”来创建Object.defineProperties,那么你现在基本上可以拥有它了。 “填充”版本会创建读写属性,因为只有本机支持的版本才能真正创建只读属性,但是您现在可以编写代码并知道它可以在现代浏览器上按您喜欢的方式工作(大约一半目前所有的网络冲浪者都拥有它们),同时仍然可以在不太现代的网络上工作,只是鲁棒性较差。

    当然,EMCAScript6 可能会更进一步,但这仍然是未来的事情。

    【讨论】:

    • 感谢您花时间回答并提供 ES5 信息。您是否知道在浏览器内存管理方面,实现 1 如何存储其私有变量与实现 2 如何存储其公共属性?我试图分析内存消耗,但我只能发现实现 2 使 MyApp 的对象大小更大,而实现 1 没有。但我知道实现 1 必须在某处存储对私有变量的引用。
    • @steve_ut:它存储在调用匿名函数的执行上下文变量绑定对象中(深呼吸) '用于创建对象。 (whew) :-) 那是 ES5 spec 术语 (canonical link)。对函数的每次调用都会获得一个变量绑定对象,该对象包含函数的参数、它的本地变量以及其他一些作为属性的东西。此处使用旧术语进行描述 Closures are not complicated.
    • @steve_ut:或者实际上,更正确地说,它存储在通用内存池中,并且变量绑定对象有对它的引用。这也是查看MyApp 对象的更正确方法;无论您使用什么工具来映射MyApp 的大小,都会为您提供一些简化的信息。 JavaScript 是关于内存池中相互引用的对象。实现 2 中的 MyApp 对象实际上并不包含 app.Enums 引用的对象,而不是实现 1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 2014-08-11
    • 2011-07-02
    • 2014-06-19
    • 2014-05-19
    • 2016-06-13
    • 1970-01-01
    相关资源
    最近更新 更多