我知道 JavaScript 通过引用传递对象,因此我在使用以下代码时遇到了很多麻烦:
function doGradeAssignmentContent(dtos) {
var x = 5;
var allPages = [];
var stage = new App.UI.PopUpDisplay.PopUpStageAssignmentGrader(null, that);// pass launch element
for(var i = 0; i < dtos[0].result.students.length; ++i) {
var pagesSet = [];
for(var j = 0; j < dtos[0].result.questions.length; ++j) {
var questionObject = jQuery.extend(true, {}, new Object());
questionObject = dtos[0].result.questions[j];
if(dtos[0].result.students[i].answers[j].assignmentQuestionId === questionObject.questionId) {// expected, if not here something is wrong
questionObject.answer = dtos[0].result.students[i].answers[j].studentAnswer;
questionObject.pointsReceived = dtos[0].result.students[i].answers[j].pointsReceived;
} else {
var theAnswer = findAssociatedStudentAnswer(questionObject.questionId, dtos[0].result.students[i].answers[j]);
if(theAnswer !== null) {
questionObject.answer = theAnswer.studentAnswer;
questionObject.pointsReceived = theAnswer.pointsReceived;
} else {
alert("Unexpected error. Please refresh and try again.");
}
}
pagesSet[pagesSet.length] = new App.UI.PopUpDisplay.StageAssignmentGradingPages[dtos[0].result.questions[j].questionType.charAt(0).toUpperCase() + dtos[0].result.questions[j].questionType.slice(1) + "QuestionAssignmentGradingPage"](j + 1, questionObject);
}
var studentInfo = {};
studentInfo.avatar = dtos[0].result.students[i].avatar;
studentInfo.displayName = dtos[0].result.students[i].displayName;
stage.addPageSet(pagesSet, studentInfo);
}
stage.launch();
}
首先让我向您展示结果(dtos)的样子,以便您更好地理解该函数是如何解析它的:
结果(dtos)是一个对象,看起来像:
- dtos 数组
- dtos[0],静态总是在这里
- dtos[0].result,静态总是在这里
- dtos[0].questions 数组
- dtos[0].questions.index0 - indexN。这描述了我们的问题,每一个都是一个对象
- dtos[0].students 数组
- dtos[0].students[0]-[n].answers 数组。每个学生数组/对象都有一个 Answers 数组。每个学生将在此答案数组中拥有与 dtos[0].questions 中的问题一样多的元素。每个元素都是一个对象
现在我们在这里做的是创建这个对象阶段。这里重要的是它有一个名为“this.studentsPages”的数组。该数组最终将包含与 dtos[0].students 中的学生一样多的条目。
所以我们遍历这个 for 循环,剖析 dtos 数组并创建一个 pagesSet 数组。我的问题来了。在 for 循环的第一次迭代中,我创建了这个 questionObject 元素。我也试过只做 var questionObject = {},但你现在看到的只是试图解决我看到的问题,但它也不起作用。
因此,在外部 for 循环的第一次迭代结束时,我调用 stage.addPageSet,这就是这里发生的情况:
var pageObject = [];
pageObject["questions"] = pageSet;
pageObject["displayName"] = studentInfo.displayName;
this.studentsPages[this.studentsPages.length] = pageObject;
if(this.studentsPages.length === 1) {// first time only
for(var i = 0; i < pageSet.length; ++i) {
this.addPage(pageSet[i]);
}
}
这里需要注意的重要一点是我将 pageObject 添加到 this.studentsPages 上,这是第一次调用之前的空数组。pageObject 现在有 pageSet 以及更多信息。请记住,pageSet 是一个对象,因此通过引用传递。
在 for 循环的下一次迭代中,当我点击这一行时:
questionObject.answer = dtos[0].result.students[i].answers[j].studentAnswer;
它出错了。这会更改 questionObject 的本地副本,但它也会更改传递给 addPageSet 并在第一次迭代中添加到 studentsPages 数组的 questionObjec 的副本。所以,如果我只有 2 个学生进来,那么当一切都说完之后,studentPages 包含 2 个相同的对象。这不应该是真的。
问题是 doGradeAssignmentContent 函数中的 questionObject 保留对在前一次迭代中创建的对象的引用,然后在所有后续迭代中覆盖它。
我能做些什么来解决这个问题?
谢谢您的帮助!