Experiencing a crash is not the sole unfavorable outcome when code is executed. Cases where the code runs but provides an incorrect result are equally important, if not more so. Your examination could be along the lines of:
for(var i=0,len=arr.length;i<len;i++){
In the scenario above, it is assumed that the value of arr.length is a numerical value greater than or equal to zero. If arr does not possess a length property, or its value is not a non-negative number, the behavior of the for loop will deviate from expectation (e.g. leading to an error or an infinite loop).
obj[arr[i]]=0;
In this particular line, the outcome of evaluating arr[i]
is utilized as a property name. Therefore, in cases where this expression results in something unsuitable as a property name, an error will occur. For instance, if arr[i]
is an ActiveX object, unexpected consequences can be anticipated. If it's a native Object, the value will be the outcome of calling its toString method, which may yield identical values for different objects, trigger an error, or simply "work".
for(i in obj){
will cycle through all enumerable properties of obj, including those inherited. If an enumerable property is added to Object.prototype, it will be included in the iteration, making it typical to leverage a hasOwnProperty test to exclude inherited properties.
The extent to which you evaluate for errors hinges on the environment where the code is intended for use. If there is control over the situation and documented values expected to be fed into the function (e.g. array of primitive values), minimal (or no) testing of input values can suffice. In case an ActiveX object is passed instead of an array resulting in issues, responding with "RTFM" might be justified.
Conversely, if anticipation exists regarding the utilization of the code in a library across uncontrolled and diverse scenarios, checking that the input contains a non-negative, numeric length property seems rational, as does incorporating a hasOwnProperty test to the for..in loop.
The degree of time and effort dedicated to fortifying your code corresponds to the envisaged runtime environment. Nevertheless, initiating sensible and evident checks upfront could potentially prevent future complications. Hence, I would implement something similar to:
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;
}