The for loop doesn't work?


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>My first website!</title>
    <script type="text/javascript" src="JScript.js"></script>
</head>
<body>
<script type="text/javascript">

//The "MovieTickets" constructor's properties will be used to add on an HTML table to retrieve info. The constructor will automatically be initialzed when a prototype of a different constructor is called.
function MovieTickets(productId, customerName, film, showings) {

    this.productId = productId;
    this.customerName = customerName;
    this.film = film;
    this.showings = showings;

}

//The prototype's method will be used to return the properties to display on the HTML table.
MovieTickets.prototype.getProductId = function () { return this.productId; };
MovieTickets.prototype.getCustomerName = function () { return this.customerName; };
MovieTickets.prototype.getFilm = function () { return this.film; };
MovieTickets.prototype.getShowings = function () { return this.showings; };

//The "booking" property is added to have it's array element to automatically create an "MovieTickets" instance.
function bookingSummary() { this.booking = []; };

/*The "ticketInfo" method will be used for it's arguments to automatically be copied into the "MovieTickets" constructor arguments. Once the    "productId" is used, the "booking" property's array will create a new "MovieTickets" instance object, which it's arguments will be            automatically copied from the "ticketInfo" method.
*/
bookingSummary.prototype.ticketInfo = function (productId, customerName, film, showings) {

/* Once the "productId" is used, the "booking" property's array element will create a "MovieTickets" instance, which it's arguments are copied   from the "ticketInfo" method to display the "MovieTickets" methods to display on the HTML table.
*/
    this.booking[productId] = new MovieTickets(productId, customerName, film, showings);

}

/* Create an HTML table method that's used from the "booking" property's array element that will be used to retrieve the "MovieTickets"    methods from it's prototype.

The "getHTMLTable" method will be called after the "ticketInfo" method is invoked.
*/
bookingSummary.prototype.getHTMLTable = function () {

    var htmlTable = '<table border=1>',
        table,
        movie = this.booking;

    //Enumerate the data to create a table that's based on the methods from the "MovieTicket's" method.
    for (table in movie) {

        htmlTable += '<tr><th>';
        htmlTable += 'ProductId';
        htmlTable += '</th>';

        htmlTable += '<th>'
        htmlTable += 'Customer Name';
        htmlTable += '</th>';

        htmlTable += '<th>';
        htmlTable += 'Film';
        htmlTable += '</th>';

        htmlTable += '<th>';
        htmlTable += 'Showings';
        htmlTable += '</th></tr>';

        htmlTable += '<tr><td>';
        htmlTable += movie[table].getProductId();
        htmlTable += '</td>';

        htmlTable += '<td>';
        htmlTable += movie[table].getCustomerName();
        htmlTable += '</td>'

        htmlTable += '<td>';
        htmlTable += movie[table].getFilm();
        htmlTable += '</td>';

        htmlTable += '<td>';
        htmlTable += movie[table].getShowings();
        htmlTable += '</td></tr>';
    }

    htmlTable += '</table>';
    return htmlTable;
}

var ticketInfo1 = new bookingSummary();
ticketInfo1.ticketInfo(7283, 'John Doe', 'The Dark Knight Rises', '18 Wed July 2012');
ticketInfo1.ticketInfo(7149, 'Mary Jay', 'The Avengers', '5 May Friday 2012');

//Display in HTML.
document.write(ticketInfo1.getHTMLTable());

</script>
</body>
</html>

[FONT=Georgia]Hi you guys. I have a quick question about trying to use the for loop to loop around “movie”. When I try to execute it in the page, it doesn’t work. But instead I’m using the for-in loop to loop around the “movie array” and of course it works well as expected. It’s been said using the for loop is the better approach when looping through the array, because it lead to logical errors especially when you’re using the Array.prototype. But why is it that the for loop doesn’t work?

I apologize for the long comments in my coding it’s not structured properly the way I wanted it, due to cut and paste. You don’t need to read all of that.

Thanks.[/FONT]

It’s because you don’t actually have an array of items that start from a 0-based index and work their way up sequentially.
Instead, you are setting separate items within the arry with a custom index, for example:


this.booking[7283] = new MovieTickets(7283, 'John Doe', 'The Dark Knight Rises', '18 Wed July 2012');
this.booking[7149] = new MovieTickets(7149, 'Mary Jay', 'The Avengers', '5 May Friday 2012');

You can resolve that by letting the array index itself automatically, with:


this.booking.push(new MovieTickets(productId, customerName, film, showings))

After which using a for loop to loop through the length of the array results in the correct behaviour.


for (i = 0; i < movie.length; i += 1) {
    ...
    htmlTable += movie[i].getProductId();
    ...
}

Thanks for the response, Paul.

In other words, the Array index doesn’t see the “MovieTickets” constructor?

It only sees what it has access to.

When you use a for loop to loop from 0 up to the end of the array length, and there are only two items in the array, an item at 7149 and an item at 7283, the array is 7284 items long (because 0 is included too).

Using a loop such as this:


for (i = 0; i < movies.length; i += 1) {

}

results in all of the undefined items of the array being accessed too, such as movies[0] and movies[6000]. That’s a problem when the only items in the array are at movies[7149] and movies[7284]

So it is the type of data structure being used that is the problem there. There are several other types of data structures that can be chosen from, some of which do a better job.

Oh ok. I understand more better now. Sometimes programming can be quite frustrating.

Thanks for giving me a deeper understanding.