Какие значения приведут к сбою этой функции? - PullRequest
0 голосов
/ 16 февраля 2012

Я думаю использовать следующую функцию:

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;
}

Функция немного изменена, оригинал можно найти здесь

Тем не менее, я уверен, что есть некоторые значения, которые приведут к сбою, и я хочу точно знать, какие значения будут (так что я могу что-то с этим поделать)

Ответы [ 3 ]

2 голосов
/ 16 февраля 2012

Что ж, если arr не является массивоподобным объектом (например, с length и индексированными свойствами), он будет аварийно завершать работу.

Однако он может также не выполнять то, что вы ожидаете, когда данныев arr не массив строк.В этом случае вы получите массив обратно только со строками, исходные объекты и их тип данных будут потеряны.Но это не даст сбой ...

1 голос
/ 16 февраля 2012

Сбой - не единственный неудобный результат выполнения кода.Также (возможно, больший) интерес представляют случаи, когда код выполняется, но возвращает неверный результат.Ваш анализ может выглядеть примерно так:

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;
}
0 голосов
/ 16 февраля 2012

Woohoo!Я разбил его, где мой приз?

var arr3 = delDups(eval());
...