JavaScript Associate Array访问返回“literal”数组原型代码

时间:2013-02-16 19:34:07

标签: javascript function prototype

这是我的学校项目到目前为止的代码(使用 Murach的JavaScript和Ray Harris的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()”函数的结尾)并访问数组时, 它将原型中的“文字”代码填充到文本区域(并且无法在下一行找到平均值):

我没有足够的回复点来发布图片,但这是我的输出(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;
}

任何帮助表示欢迎(欢迎最佳做法或算法建议)

3 个答案:

答案 0 :(得分:1)

这很简单:Do not use for…in enumerations for looping Arrays!您可以在clearScoreupdate函数中执行此操作。

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

答案 1 :(得分:1)

改变这个:

studentScores = []

到此:

studentScores = {}

...这样你就可以使用Object而不是Array。

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

将您的average()方法设置为与其他方法一样的独立功能,并将studentScores传递给它以计算平均值,然后使用for-in代替for。< / p>

答案 2 :(得分:0)

您必须决定studentScores是否为数组(即,整数用于访问存储的数据)或Object / Associative Array(字符串用于设置/获取元素)。

如果你想使用学生的名字作为关键,你应该将studentScores声明为一个对象,并且你的'普通'方法必须添加到Object原型中(我不推荐)。

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

> a = [];
[]
> a['foo'] = 'bar';
'bar'
> a.length
0
> a[3] = 0;
0
> a.length
4