Object Oriented JavaScript: How would you go about this?
As I've gotten to know JS better, I've moved from a procedural style to semi-OO (don't ask me what I mean by that: a mess basically!) but now I want to start using it properly. OO appeals to my coding-brain.
However, I'm trying to develop a library of school weeks, and I'm not sure how I'd best go about it.
If I was to simply use an array of weeks, they would look something like this:
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";
- Key: Week number according to School Calendar
- StartDate / EndDate: MySQL-compatible date ranges
- JSDate: JS date object of start of week
- Type: school timetable, week 1 or 2
- Label: human-readable label indicating start of week
I would like this library to be accessible by other scripts, so that they can load an Array or Object containing all of the weeks in the school calendar. I'd imagi开发者_JS百科ne, for instance, one of my scripts producing a drop-down menu from this information, which displays "Week 36: 5th Sept 2011" and when clicked upon sends a request to my PHP script & SQL database then filters the information on screen accordingly. NOTE: I don't need help with the implementation of the latter, it's just an example for context.
I started coding as follows:
var LEAP = {}
LEAP.Schedule = {
init: function() {
this.setWeeks();
}
setWeeks: function() {
var WeeksArray = [];
But the more I look at it, the less correct it feels!
Should I be creating "Week" objects, then a container for them which has a method to return all of the Week objects? I've been reading the OOP chapter in "Pro JavaScript Techniques" by John Resig, but truth be told I don't fully understand it. This feels like the right approach, but an Object within an Object is hurting my head.
The final outcome should be that I include this script on one of my pages, then can use something like var WeeksArray = LEAP.Schedule.getWeeks();
, but even then I'm not sure that's realistic?
I'm rather confused...! :D Any help on the subject would be hugely appreciated.
setWeeks: function(){
var WeeksArray = []; //This variable is private, which is probably not your desired result.
}
^ That doesn't work, see comment.
I'd recommend something like this: External file:
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;
}
Main file:
var Scheduleobject = new LEAP.Schedule();
var weeks = Scheduleobject.getWeeks();
This feels like a very natural OOP approach, to me. You can even change the LEAP.Schedule function such that it returns the Weeks array immediately, dependent on the situation.
EDIT
An example of a week class:
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.
The week class can be called in this way:
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`
Following up on my comment.
You might not ever need formal week objects. It might be enough to simply store which weeks are which type, and a formula for converting the number to a date. So your Calendar or Schedule object might have a property indicating the absolute day that week number 1 starts, and an array of week types in order. Then when getWeeks() is called, it can start at week 1 and build an array of the necessary weeks, which could be formal objects, or could simply be associative arrays:
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)
}
Hopefully that starts you on the right track, I'm happy to help if I can provide further clarification.
精彩评论