我正在考虑使用以下功能:
function delDups(arr){
var out=[],obj={};
for(var i=0,len=arr.length;i<len;i++){
obj[arr[i]]=0;
}
for(i in obj){
out.push(i);
}
return out;
}
该功能略有修改,原始版本为here
但是,我确信有一些值会让它崩溃,我想知道究竟会有什么值(所以我可以做些关于它的事情)
答案 0 :(得分:2)
好吧,如果arr
不是类似数组的对象(例如,使用length
和索引属性),它将崩溃。
然而,只要arr
中的数据不是字符串数组,它也可能无法达到预期效果。在这种情况下,您只能使用字符串返回数组,原始对象及其数据类型将丢失。但它不会崩溃......
答案 1 :(得分:1)
崩溃并不是执行代码的唯一不方便的结果。 (也许更大)兴趣的是代码运行但返回错误结果的情况。您的分析可能类似于:
for(var i=0,len=arr.length;i<len;i++){
在上文中,假设arr.length的值是大于或等于零的数值。如果 arr 没有长度属性,或者其值不是非负数,则for循环将不会按预期运行(例如,它可能导致错误或无限循环)。
obj[arr[i]]=0;
在这一行中,评估arr[i]
的结果被用作属性名称,因此只要该表达式返回不适合作为属性名称的内容,就会出现错误,例如:如果arr[i]
是ActiveX对象,则可能会出现意外结果。如果它是本机对象,则该值将是调用其toString方法的结果,该方法可能为不同的对象提供相同的值,或者出错,或者“只是工作”。
for(i in obj){
将遍历 obj 的所有可枚举属性,包括它继承的属性。如果将一个可枚举属性添加到 Object.prototype ,它将在循环中出现,因此通常使用 hasOwnProperty 测试来过滤掉继承的属性。
您测试错误的程度取决于您希望使用代码的环境。如果您有合理的控制并记录了预期传递给函数的值(例如原始值数组),那么它对输入值进行最小(或没有)测试是合理的。如果有人传入一个ActiveX对象而不是一个数组,然后它就会响起来,你会回复“RTFM”。
另一方面,如果已知代码将在不受控制且变化很大的情况下在库中使用,那么测试输入具有非负数字长度属性似乎是合理的,添加 hasOwnProperty 测试for..in循环。
您在使代码运行时所花费的时间和精力取决于您期望它运行的位置,但是预先添加一些合理且明显的检查可能会在以后节省一些悲伤。所以我会做类似的事情:
function delDups(arr) {
var out=[],obj={};
var len = arr && arr.length;
if (len && len > 0) {
for(var i=0; i<len; i++) {
obj[arr[i]] = 0;
for (i in obj) {
if (obj.hasOwnProperty(i)) {
out.push(i);
}
}
}
return out;
}
答案 2 :(得分:0)
哇噢!我撞了它,我的奖品在哪里?
var arr3 = delDups(eval());