【问题标题】:javascript object literal pattern with multiple instances具有多个实例的 javascript 对象文字模式
【发布时间】:2011-04-24 05:00:33
【问题描述】:

我开发了一个小的 javscript 小部件来将一些嵌套的 <ul> 块转换为 Windows 资源管理器风格的浏览器。我最近了解了对象文字模式并决定试一试,所以我的代码组织是这样的:

var myExplorer = {
    init : function(settings) {
        myExplorer.config = {
            $wrapper : $('#explorerCategories'),
            $contentHolder : $j('#categoryContent'),
            loadingImg : '<img src="../images/standard/misc/ajax_loader.gif" alt="loading" class="loading" />'
        }
        // provide for custom configuration via init()
        if (settings && typeof(settings) == 'object') {
            $.extend(myExplorer.config, settings);
        }

        // some more code...
    },

    createExpanderLink : function() {
        // more code
    },

    anotherMethod : function() {
        // etc
    }
}

然后在我的页面中我设置了我的资源管理器:

$j(function () {
    myExplorer.init();
}

顺便说一句,这一切都很好。问题是当我想在同一页面上拥有多个这些资源管理器样式小部件时。我尝试传入不同的设置:

$j(function () {
    // first instance
    myExplorer.init();

    //second instance
    var settings = {
        $wrapper : $('#explorerCategories2'),
        $contentHolder : $j('#categoryContent2')
    }
    myExplorer.init(settings);

}

但这只是覆盖了第一个实例的配置值,从而有效地破坏了它。我开始意识到对象文字模式不是去这里的方式,但我不确定是什么。有没有人可以指点一下?

【问题讨论】:

    标签: javascript jquery object


    【解决方案1】:

    在对象字面量上使用函数代替,因此您可以使用 new 关键字实例化小部件的多个对象。

    function myExplorer(settings) {
        // init code here, this refers to the current object
        // we're not using a global object like myWindow anymore
        this.config = {
            $wrapper : $('#explorerCategories'),
            $contentHolder : $j('#categoryContent'),
            ..
        };
    
        // provide for custom configuration
        if (settings && typeof(settings) == 'object') {
            $.extend(this.config, settings);
        }
    
        this.someFunction = function() { 
            ..
        };
    
        this.otherFunction = function() {
    
        };
    }
    

    根据需要实例化这个小部件的尽可能多的对象,

    var foo = new myExplorer({ .. });
    var bar = new myExplorer({ .. });
    ...
    

    【讨论】:

    • 请原谅我的无知,但是当使用这种模式时,我必须先声明所有内部函数,然后才能在周围的 myExplorer 函数中使用它们。我只是对您的 //init code here 评论感到有些困惑。
    【解决方案2】:

    这个怎么样?

    var myExplorer = 函数(设置){ var o = { 初始化:函数(){ this.somevalue = 设置; }, 随便:函数(){ } }; o.init(); 返回 o; }; var exp1 = myExplorer('something'); var exp2 = myExplorer('anything'); 控制台.log(exp1.somevalue); //某物 控制台.log(exp2.somevalue); //任何事物

    【讨论】:

      【解决方案3】:

      使用以下代码来实现这一点,请记住“公共 API”(这样“内部”功能将在“外部”可见):

      var myExplorer = function() {
          var init = function(settings) {
              var config = {
                  $wrapper : $('#explorerCategories'),
                  $contentHolder : $j('#categoryContent'),
                  loadingImg : '<img src="../images/standard/misc/ajax_loader.gif" alt="loading" class="loading" />'
              }
              // provide for custom configuration via init()
              if (settings && typeof(settings) == 'object') {
                  $.extend(config, settings);
              }
      
              // some more code...
          },
      
          var createExpanderLink = function() {
              // more code
          },
      
          var anotherMethod = function() {
              // etc
          }
      
          // Public API 
          // return the functions you want to use outside of the current instance
          return {
              init : init,
              createExpanderLink : createExpanderLink,
              anotherMethod : anotherMethod
          }
      }
      var firstExplorer = new myExplorer();
      var secondExplorer = new myExplorer();
      // etc 
      

      【讨论】:

        【解决方案4】:

        当你像这样调用$.extend() 时,它会将第二个对象的属性合并到第一个对象中:

        $.extend(myExplorer.config, settings);
        

        相反,创建一个 new 对象,该对象是合并的结果,而第一个对象(默认值)保持不变,如下所示:

        this.settings = $.extend({}, myExplorer.config, settings);
        

        它所做的仍然是将传递的对象合并到第一个对象中,但第一个对象是一个新对象({}),所以我们不会影响其他任何一个,然后只需使用this.settings(或其他名称以使其绝对清晰)在您的对象中。

        【讨论】:

        • 谢谢。我试过了,但它对我不起作用。虽然它在 myExplorer 对象中创建了一个新的设置对象,但这些值仍然被第二个 myExplorer.init(settings) 调用覆盖。
        • @ben - 我什至没有查看您的对象结构,您只有一个对象,您需要使用上述方法创建完全不同的路径,Anurag 的答案是一种可能,这里有很多模式。
        【解决方案5】:

        据我了解,您正在尝试创建一个使用对象文字符号定义的新对象实例。 可以使用 Object.create 方法实例化对象字面量。 下面是解释如何从对象字面量表示法实例化对象的代码。

                    var objLiteral = {
                        name:"kanthan",
                        address:'',
                        deliver:function(){
                            if(this.address){
                                console.log("Your product has been successfully delivered at "+this.address);
                            }
                            else{
                                console.log("please enter the address to deliver");
                            }
                        }
                    };
                    var cum=Object.create(objLiteral);
                    cum.address="gkm colony";
                    objLiteral.deliver();
                    cum.deliver();
                    var cum1=objLiteral;
                    cum1.address="gkm colony";
                    objLiteral.deliver();
                    cum1.deliver();
        

        【讨论】:

          猜你喜欢
          • 2015-02-02
          • 2015-06-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多