2013-02-16 54 views
0

以下是我的学校项目的代码(使用Murach的Ray Harris的Murach JavaScript和DOM脚本)。本章仅约数组,不包括原型,但我想尝试一下基于Internet的教程和参考:JavaScript关联数组访问返回“literal”数组原型代码

/* 
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(); 
} 

当代码进入“更新()”功能(“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; 
} 

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

+0

你什么时候实际调用'output'? – 2013-02-16 19:43:02

+0

什么'output()'函数,什么数组? – melpomene 2013-02-16 19:44:49

+0

哎呀......“update()”函数就是我的意思,编辑 – PAINKILLER 2013-02-16 20:19:56

回答

1

更改此:

studentScores = [] 

这样:

studentScores = {} 

...让你使用一个对象而不是数组。

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

创建average()方法和别人一样一个独立的功能,并通过studentScores它来计算平均值,然后用for-in,而不是for

+0

您确切知道我要做什么并解决了您的解决方案 - 谢谢! – PAINKILLER 2013-02-16 20:44:30

+0

@Humanodude:不客气。 – 2013-02-16 20:46:07

1

这很简单:Do not use for…in enumerations for looping Arrays!您在clearScoreupdate函数中这样做。

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

+0

好的建议,谢谢。我结束了与'去... ...因为我想要使用关联数组(正确) – PAINKILLER 2013-02-16 20:47:38

0

您必须决定是否打算将studentScores作为数组(即用于存取数据的整数)或对象/关联数组(用于设置/获取元素的字符串)。

如果你想使用学生的名字作为键,你应该声明studentScores为一个对象,你的'平均'方法将被添加到对象原型(我不建议)。

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

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

“对象/关联数组” - 感谢您对对象与数组索引的帮助解释,并带有示例 – PAINKILLER 2013-02-16 20:46:19