【问题标题】:Object Oriented JavaScript: How would you go about this?面向对象的 JavaScript:你会怎么做?
【发布时间】:2011-09-12 11:21:53
【问题描述】:

随着我对 JS 的了解越来越深入,我已经从程序风格转向了半 OO(别问我这是什么意思:基本上是一团糟!)但现在我想开始使用它适当地。 OO 吸引了我的编码大脑。

但是,我正在尝试开发一个学校周图书馆,但我不确定我最好如何去做。

如果我只是简单地使用一个星期数组,它们看起来像这样:

    WeeksArray[36].StartDate = "2011-09-05";
    WeeksArray[36].EndDateSchool = "2011-09-09";
    WeeksArray[36].EndDateProper = "2011-09-11";
    WeeksArray[36].JSDate = new Date ( 2011, 8, 05 );
    WeeksArray[36].Type = "1";
    WeeksArray[36].Label = "Week 36: 5th Sept 2011";
  • :根据校历的周数
  • StartDate / EndDate:与 MySQL 兼容的日期范围
  • JSDate:一周开始的 JS 日期对象
  • 类型:学校时间表,第 1 周或第 2 周
  • 标签:指示一周开始的人类可读标签

我希望其他脚本可以访问此库,以便它们可以加载包含学校日历中所有周的数组或对象。例如,我会想象我的一个脚本会根据这些信息生成一个下拉菜单,其中显示“第 36 周:2011 年 9 月 5 日”,然后单击时向我的 PHP 脚本和 SQL 数据库发送请求,然后过滤信息相应地出现在屏幕上。 注意:后者的实施我不需要帮助,这只是上下文的示例。

我开始编码如下:

var LEAP = {}

LEAP.Schedule = {

    init: function() {
        this.setWeeks();
    }

    setWeeks: function() {
        var WeeksArray = [];

但越看越觉得不正确!

我是否应该创建“Week”对象,然后为它们创建一个容器,该容器具有返回所有 Week 对象的方法?我一直在阅读 John Resig 的“Pro JavaScript Techniques”中的 OOP 章节,但说实话我并不完全理解它。这感觉是正确的方法,但是对象中的对象让我很头疼。

最终结果应该是我将这个脚本包含在我的一个页面上,然后可以使用var WeeksArray = LEAP.Schedule.getWeeks(); 之类的东西,但即便如此我也不确定这是否现实?

我很困惑……! :D 对此主题的任何帮助将不胜感激。

【问题讨论】:

  • 我认为您可能拥有 Weeks 对象,但您不需要直接设置这么多属性。所有与日期相关的都应该从您传递的任何日期推断出来。
  • 我同意 Rob W 的做法。 OOP 有利于简化复杂性,但是当您的复杂程度是一些计算和哈希查找时,无需过度构建高度结构化的类。您基本上比内置运算符和语言特性抽象了一步,因此只需一个类(或者在这种情况下,甚至只有一个命名空间)就足以封装复杂性。

标签: javascript oop


【解决方案1】:
setWeeks: function(){
  var WeeksArray = []; //This variable is private, which is probably not your desired result.
}

^ 这不起作用,请参阅评论。

我会推荐这样的东西: 外部文件:

var LEAP = {};
LEAP.Schedule = function(){//init
  //all events which should only occur once should be called here
  //Create the initial objects, e.g.
  this.weeks = [];
  this.calculateWeeks();
}
LEAP.Schedule.protoype.calculateWeeks = function(){
  for (var i=0; i<52; i++){
    this.weeks.push(Math.random()); //For the sake of the example ;)
  }
}
LEAP.Schedule.prototype.getWeeks = function(){
  return this.weeks;
}

主文件:

var Scheduleobject = new LEAP.Schedule();
var weeks = Scheduleobject.getWeeks();

对我来说,这感觉像是一种非常自然的 OOP 方法。 您甚至可以更改 LEAP.Schedule 函数,使其根据情况立即返回 Weeks 数组。

编辑

一周课的例子:

LEAP.Schedule.week = function(n_year, n_month, n_day, n_week){
  //add code to validate the input
  //...
  //finished validating, processing:
  this.year = n_year;
  this.month = n_month;
  this.day = n_day;
  this.week = n_week;
}
LEAP.Schedule.week.protoype.getStartDate = function(){
  return year + "-" + pad(month) + "-" + pad(day);
}
//LEAP.Schedule.week.prototype.*Date are defined in a similar way
//The "EndDateSchool" and "EndDateProper" variables always follow the same pattern. Reduce the number of unnecessary variables by calculating these variables in the prototype function.
LEAP.Schedule.week.prototype.getLabel = function(){
  return "week" + this.week + ": " + this.day + (day==1||day==21||day==31?"st":day==2||day==22?"nd":day==3||day==23?"rd":"th") + " " + ["jan", "feb", "mar", "etc"][this.month-1] + " " + this.year;
}
function pad(n){return n>9?n:"0"+n}//a simple function to add a zero for your specific cases.

可以这样调用周课:

var week = new Schedule.Week(2011, 8, 5, 36); //or this.Week(2011, 8, 5, 36) from the contex of the class.
var startDate = week.getStartDate(); //example`

【讨论】:

  • 感谢罗布。您在这里描述的是我最初处理事物的方式(尽管是错误的;) - 可以通过函数返回的周数数组。您说这是一种非常自然的 OOP 方法,但是为数组中的每一行都有一个新的 Week 对象不是“更好”(不确定在此处使用什么其他词)吗?
  • @dunc 查看我的更新答案。不要过度使用 OOP 概念。不鼓励创建几个在类之外没有目的的额外方法。
【解决方案2】:

跟进我的评论。

您可能永远不需要正式的一周物品。简单地存储哪些星期是哪种类型,以及将数字转换为日期的公式可能就足够了。因此,您的 Calendar 或 Schedule 对象可能具有指示第 1 周开始的绝对日期的属性,以及按顺序排列的周类型数组。然后当 getWeeks() 被调用时,它可以从第 1 周开始并构建一个包含必要周数的数组,它可以是正式的对象,也可以只是关联数组:

weeks = [];
for (var i = 0; i < this.week_types.length; i++){
    weeks[i] = {
    "StartDate": this.get_start_date(i),
    "JSDate": this.get_js_date(i),
    ..., //The rest of the properties
    "type": this.week_types[i],
    "Label": this.get_label(i)
}

希望这能让您走上正确的道路,如果我能提供进一步的说明,我很乐意提供帮助。

【讨论】:

  • 谢谢亚历克。我确实会记住这一点 - 这是我最初想要做的,但为了清楚起见这篇文章决定使用手动输入的数组。
  • 我通常更喜欢使用普通对象,但在这种情况下,Week 对象可能是更好的选择。 Alec Munro 提出的代码会发生什么?循环创建一个新对象,立即执行几个函数,以计算可能永远不会使用的值。此外,当周算法更改时,必须再次重新创建对象。如果使用周对象,会设置一些原始值,可以在调用继承(原型)函数时使用。
  • Rob 是正确的,我的解决方案是一个非常低效的解决方案。这对您的实施可能无关紧要,但您始终可以在创建 Schedule 时初始化几周。或者,正如我认为 Rob 所建议的那样,您可以将计算函数 (get_x()) 移至 Week 类,并在您实际需要这些值时调用它们,而不是将它们作为 Week 的属性或匿名对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-19
  • 2021-06-13
  • 2010-10-21
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
相关资源
最近更新 更多