【问题标题】:encapsulation in javascript module patternjavascript模块模式的封装
【发布时间】:2012-04-28 11:11:18
【问题描述】:

我正在阅读此链接http://addyosmani.com/largescalejavascript/#modpattern

看到了下面的例子。

var basketModule = (function() {
var basket = []; //private

return { //exposed to public
       addItem: function(values) {
            basket.push(values);
        },
        getItemCount: function() {
            return basket.length;
        },
        getTotal: function(){
            var q = this.getItemCount(),p=0;
            while(q--){
                p+= basket[q].price;
            }
        return p;
        }
      }
}());

basketModule.addItem({item:'bread',price:0.5});
basketModule.addItem({item:'butter',price:0.3});

console.log(basketModule.getItemCount());
console.log(basketModule.getTotal());

它指出“模块模式是一种流行的设计,该模式使用闭包封装'隐私'、状态和组织”这与像下面这样写有什么不同?不能通过函数范围简单地强制执行隐私吗?

var basketModule = function() {
var basket = []; //private
       this.addItem = function(values) {
            basket.push(values);
        }
        this.getItemCount = function() {
            return basket.length;
        }
        this.getTotal = function(){
            var q = this.getItemCount(),p=0;
            while(q--){
                p+= basket[q].price;
            }
        return p;
        }

}

var basket = new basketModule();

basket.addItem({item:'bread',price:0.5});
basket.addItem({item:'butter',price:0.3});

【问题讨论】:

    标签: javascript module design-patterns encapsulation


    【解决方案1】:

    在第一个变体中,您创建一个对象而不能创建它的新实例(它是一个立即实例化的函数)。第二个示例是一个完整的构造函数,允许多个实例。两个示例中的封装相同,basket 数组在两个示例中都是“私有的”。

    只是为了好玩:两全其美:

    var basketModule = (function() {
       function Basket(){
            var basket = []; //private
            this.addItem = function(values) {
                basket.push(values);
            }
            this.getItemCount = function() {
                return basket.length;
            }
            this.getTotal = function(){
                var q = this.getItemCount(),p=0;
                while(q--){
                    p+= basket[q].price;
                }
            return p;
           }
         }
       return {
         basket: function(){return new Basket;}
       }
    }());
    //usage
    var basket1 = basketModule.basket(), 
        basket2 = basketModule.basket(),
    

    【讨论】:

    • 我想我现在的问题是第一个模式比第二个模式更“模块”。该链接使用第一个变体作为模块模式的明确示例。
    • 我想说第一个变体反映了模块模式(提供basketModule),第二个提供了一种创建basket instances的方法。顺便说一句,这都是标签的问题,您可以将第一个变体命名为“单例模式”。
    • 从模块是一个独立的功能包而不是一组可实例化的类的观点来看,是的。然而,两者之间的区别不是设计,而是语法。拥有var basketModule = new function(){...};,没有什么能阻止你以第二种方式拥有单身人士。使用返回对象的想法是,如果您愿意,可以将接口压缩成几行代码,这样您就可以一目了然。但是您不会为此使用大型匿名函数,您只需使用return {publicFunc:privateFunc};
    • @eirikrl 当涉及到新关键字时,请查看stackoverflow.com/questions/383402/… 以获得关于该主题的精彩讨论。 TL;DR 在 JavaScript 中有很多方法可以做事,而且大多数都不是完全错误的。 :)
    • 谢谢...完美的解释:)
    猜你喜欢
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 2017-05-19
    • 2013-11-10
    • 1970-01-01
    相关资源
    最近更新 更多