未捕获的类型错误:无法读取属性 - 尽管属性存在
var sorted = DocumentListData.Documents.sort(function (a, b) {
var nameA = a.Document.toLowerCase(),
nameB = b.Document.toLowerCase();
return nameA.localeCompare(nameB);
});
for (var i = 0, len = sorted.length; i < len; i++) {
if (sorted[i].Document=== 'abc') {
sorted.splice(i, 1);
}
if (sorted[i].Document=== 'xyz') {
sorted.splice(i, 1);
}
}
我花了一个小时思考这里到底出了什么错误。它抛出“Document is undefined”,尽管 Document 属性存在。
Uncaught TypeError: Cannot read property 'Document' of undefined
。当我删除
sorted.splice(i,1)
时,它可以正常工作并且没有错误。
您正在修改正在迭代的数组。
splice(i,1)
删除第 i 个元素。当您拼接排序后的数组时,您将删除元素,因此最终会超出数组的长度,因为循环会转到数组的原始长度。
sorted[i]
然后未定义,并且您会收到您所描述的错误。
通常,以这种方式修改当前正在迭代的数组从来都不是一个好主意。如果您必须以这种方式执行此操作,请确保包含 if 检查以查看
i
是否不为
>=
到数组的当前长度。但使用 while 循环可能更适合这里。
var counter =0;
while(counter < sorted.length) {
var doc = sorted[counter].Document;
if (doc === 'abc' ||doc === 'xyz') {
sorted.splice(counter, 1);
}
else{
counter++;
}
}
更多想法
-
document
是 javascript 浏览器环境中的预定义变量,通常 JS 有一个约定,即大写变量仅适用于构造函数。因此Document
可能不是一个很好的属性名称选择。 -
如果您不需要支持旧版本的 IE,您还可以查看 Array.Prototype.filter ,这是一种更简洁的方式来做您想做的事情
如果最后一个元素的
Document
是
abc
,它将在第一个
if
条件中被删除。
sorted[i]
将变为
undefined
(因为您已经删除了最后一个元素),并且当第二个
if
运行时,您将收到所描述的错误。
您可以使用
else if
来修复此问题:
if (sorted[i].Document=== 'abc') {
sorted.splice(i, 1);
} else if (sorted[i].Document=== 'xyz') {
sorted.splice(i, 1);
}