什么值会使这个功能崩溃?

时间:2012-02-16 02:07:13

标签: javascript arrays crash duplicates

我正在考虑使用以下功能:

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

但是,我确信有一些值会让它崩溃,我想知道究竟会有什么值(所以我可以做些关于它的事情)

3 个答案:

答案 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());