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

Is it better to have events within JavaScript objects or outside?

本文关键字:外部 更好 内部 对象 事件 JavaScript      更新时间:2023-09-26

在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();

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

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

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

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

  • 所有行为被封装在对象
  • 因为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();
        });
    });
}

如果你有声明或内置的东西-这并不重要,你在哪里重新定义它的值;

在你的例子中,两个代码的结果将是相同的。唯一的区别是,当你在函数或if或任何操作符之外声明:var x = "x";时,它将成为一个全局变量,并立即赋值。您还可以将空变量var x;声明为全局变量,并通过函数或任何操作符赋值,该值将保持在那里。由于window.onload是一个全局对象的事件-这无关紧要,您将值赋给它。

我只会这样做:

$(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();
}

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

第二种方法不是虽然,我只是a)调用函数像showOnLoad()不同的东西,b)使用适当的事件注册(Guffa的答案可能是注册"on load"事件的最佳方法),而不是赋值给window.onload