0

这是迄今为止我的学校项目的代码(使用Ray Harris 的 Murach 的 JavaScript 和 DOM 脚本)。这一章只是关于数组,不包括原型,但我想根据互联网教程和参考资料尝试一下:

 /*
Operation

    This application stores the last name, first name, and score for 
    one or more students and it calculates the average score for all of the scores
    that have been entered. When the user clicks on the Clear button, this 
    application clears the score data from this application. When the user clicks 
    on the Sort button, this application sorts the data in alphabetical order by 
    last name.

Specifications

    The program should use one or more arrays to store the data.
    Assume that the user will enter valid data.
*/
var $ = function (id) 
{ 
    return document.getElementById(id); 
}

/*
Array prototype object extension for averaging the contents

"Adding a method to the built-in Array object to extract the average 
of any numerical values stored in the array is therefore a useful 
addition to that object." http://javascript.about.com/library/blaravg.htm
*/
Array.prototype.average = function () 
{
    var avg = 0;
    var count = 0;
    for (var i = 0; i<this.length; i++) 
    {
       //never gets here:
        alert(i + ": " + this[i]);
        var e = +this[i];
        if(!e && this[i] !== 0 && this[i] !== '0') 
        {
            e--;
        }
        if (this[i] == e) 
        {
            avg += e;
            count++;
        }
    }   
    return avg / count;
}

var addScore = function ()
{
    studentScores[$('last_name').value + ', ' + $('first_name').value] = $('score').value;
    update();
}

var clearScore = function ()
{
    for (var i in studentScores)
    {
        studentScores[i] = '';
    }
    update();
}

var sortScore = function ()
{
    scores.sort();
    update();
}

var update = function ()
{
    var result = '';
    for (var i in studentScores)
    {
        result += (i + ': ' + studentScores[i] + '\n');
    }
    $('scores').value = result;
    $('average_score').value = studentScores.average().toFixed(1);
}

window.onload = function ()
{
    //a variable is initialized inside a function without var, it will have a global scope:
    studentScores = [];
    $('add_button').onclick = addScore;
    $('sort_button').onclick = sortScore;
    $('clear_button').onclick = clearScore;
    $('last_name').focus();
}

当代码进入“update()”函数(“addScore()”函数的末尾)并访问数组时,它会将 Prototype 中的“literal”代码填充到文本区域中(并且无法在下一行):

我没有足够的代表点来发布图像,但这是我的输出(Chrome JS 控制台中没有错误):

lowe, doug: 82
average: function () 
{
    var avg = 0;
    var count = 0;
    for (var i = 0; i<this.length; i++) 
    {
        //never gets here:
        alert(i + ": " + this[i]);
        var e = +this[i];
        if(!e && this[i] !== 0 && this[i] !== '0') 
        {
            e--;
        }
        if (this[i] == e) 
        {
            avg += e;
            count++;
        }
    }   
    return avg / count;
}

任何帮助表示赞赏(欢迎最佳实践或算法建议)

4

3 回答 3

1

这很简单:不要使用for…in枚举来循环数组!你在你的clearScoreupdate函数中这样做。

for (var prop in obj)循环遍历所有 [enumerable] 属性,包括那些继承自Array.prototype(至少对于 Array 对象)的属性。for (var i=0; i<array.length; i++)循环不会有这个问题。

于 2013-02-16T19:48:58.993 回答
1

改变这个:

studentScores = []

对此:

studentScores = {}

...这样您就可以使用对象而不是数组。

您的for循环average()只是迭代数字索引而不是您创建的非数字键。

像其他方法一样将您的方法创建average()为独立函数,并传递studentScores给它以计算平均值,然后使用for-in而不是for.

于 2013-02-16T20:09:43.520 回答
0

您必须决定 studentScores 是一个数组(即,一个整数用于访问存储的数据)还是一个对象/关联数组(一个字符串用于设置/获取元素)。

如果您想使用学生的姓名作为键,您应该将 studentScores 声明为一个对象,并且您的“平均”方法必须添加到对象原型中(我不推荐)。

根据代码的当前状态,您偶然发现 Array 也是一个对象,并且可以像任何其他对象一样附加任意属性。您已经按名称添加了属性,但在您的平均方法中,您正在尝试访问基于数字的索引。但这不是您要添加的数据的存储位置。

> a = [];
[]
> a['foo'] = 'bar';
'bar'
> a.length
0
> a[3] = 0;
0
> a.length
4
于 2013-02-16T19:54:32.877 回答