【问题标题】:Is it better to have events within JavaScript objects or outside?将事件放在 JavaScript 对象内部还是外部更好?
【发布时间】:2011-10-26 21:27:07
【问题描述】:

事件是在 JavaScript 对象内部还是外部更好?

例如,这里有一些简单的代码来生成一个在页面底部弹出的工具栏(我在这里使用 jQuery):

tool_bar = {    
  show : function() {
    $('#bottomBox')
      .show()
      .animate({ 'bottom'  : '0' }, 700)
    ;
  },
  close : function() {
    $('#bottomBox').hide();     
  }
};

$(function() {  
  $('#bottomBox span').click(function() {
    tool_bar.hide();
  });
});

window.onload = function() {
  tool_bar.show();
};

在上面我有 tool_bar 对象之外的事件。这是更好还是这样:

tool_bar = {    
  show : function() {
    window.onload = function() {
      $('#bottomBox')
        .show()
        .animate({ 'bottom' : '0' }, 700)
      ;
    };
  },
  close : function() {
    $('#bottomBox span').click(function() {
      $('#bottomBox').hide();       
    });
  }
};

$(function() {
  tool_bar.close();
});

tool_bar.show();

应该提到,两者都有效。我只是想知道什么是更好的做法。

【问题讨论】:

    标签: javascript jquery oop


    【解决方案1】:

    我建议封装是一个有价值的目标。这意味着您将对象的行为封装在该对象中。外部世界应该能够控制安装或移除对象,并且能够控制客户端可能想要的任何其他行为,但是对象“内部”的行为应该完全在对象内部实现(至少对于默认行为) .

    在您的具体情况下,我认为您应该允许外部代理安装或删除工具栏,但工具栏安装后的操作应由工具栏本身处理。

    我建议这样的实现具有以下优点:

    • 所有行为都封装在对象中
    • 因为id是传入构造函数的,所以可以有多个
    • 对象负责管理它自己的事件处理程序,外部世界不必知道这一点。
    • 它具有show()hide() 的外部可用方法。
    • 您可以轻松添加其他行为。

    你会像这样实现一个工具栏:

    var bottomToolbar = new tool_bar("bottomBox", true);
    

    还有,这是对象的代码:

    // id is a required argument
    // show is an optional argument (true means to show it as soon as possible)
    var tool_bar = function(id, show) {
        this.id = '#' + id;
    
        this.show = function() {
            $(this.id).show().animate({ 'bottom'  : '0' }, 700);
        };
    
        this.hide = function() {
            $(this.id).hide();
        };
    
        // .ready() code will either be fired immediately if document already ready
        // or later when document is ready, so the code can be used either way
        $(document).ready(function() {
            if (show) {
                this.show();
            }
            $(this.id + " span").click(function() {
                this.hide();
            });
        });
    }
    

    【讨论】:

      【解决方案2】:

      那些你已经声明或内置的东西——这并不重要,你在哪里重新定义它的价值;

      在您的情况下,两个代码的结果将是相同的。 唯一的区别是,当您在函数或 if 或任何运算符之外声明:var x = "x"; 时,它将成为全局变量并立即为其赋值。 您还可以将一个空的 var var x; 声明为全局 var,并通过函数或任何运算符分配一个值,该值将保留在那里。 因为window.onload 是一个全局对象的事件——没关系,你在哪里给它赋值。

      【讨论】:

        【解决方案3】:

        我会这样做:

        $(function() {  
        
          var bottom = $('#bottomBox')
            .show()
            .animate({
              'bottom': '0'
            }, 700);
        
          $('span', bottom).click(function() {
            bottom.hide();     
          });
        
        });
        

        你也可以把它做成一个插件:

        $.fn.toolbar = function(){
        
          this
            .show()
            .animate({
              'bottom': '0'
            }, 700);
        
          $('span', this).click(function() {
            $(this).parent().hide();     
          });
        
          return this;
        
        }
        
        $(function() {  
        
          $('#bottomBox').toolbar();
        
        }
        

        【讨论】:

        • 看来 OP 有一个 show() 方法是有充分理由的。隐藏后,能再次显示出来就好了。您的实现不再有 show() 方法。
        • @jfriend00:好像不是这样。问题中的第二个实现没有这样的 show 方法。
        • 好的,但是第一个实现可以。
        【解决方案4】:

        我赞成将机制和策略分开,因此在您的示例中,我将以第一种方式构建我的代码。

        第二种方式也不错不好,但我只想 a) 调用不同的函数,例如 showOnLoad(),b) 使用适当的事件注册(Guffa 的答案可能是最好的注册“加载”事件的方式),而不是分配给window.onload

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-06-20
          • 2013-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-10
          • 1970-01-01
          相关资源
          最近更新 更多