Asked  7 Months ago    Answers:  5   Viewed   35 times

The below function works fine on Opera, Firefox and Chrome. However, in IE8 it fails on the if ( allowed.indexOf(ext[1]) == -1) part.

Does anyone know why? Is there any obvious mistake?

function CheckMe() {
    var allowed = new Array('docx','xls','xlsx', 'mp3', 'mp4', '3gp', 'sis', 'sisx', 'mp3', 'wav', 'mid', 'amr', 'jpg', 'gif', 'png', 'jpeg', 'txt', 'pdf', 'doc', 'rtf', 'thm', 'rar', 'zip', 'htm', 'html', 'css', 'swf', 'jar', 'nth', 'aac', 'cab', 'wgz');
    var fileinput=document.getElementById('f');
    var ext = fileinput.value.toLowerCase().split('.');
    if ( allowed.indexOf(ext[1]) == -1) 
    {
        document.getElementById('uploadsec').innerHTML = document.getElementById('uploadsec').innerHTML;
        alert('This file type is not allowed!');
    }
}

 Answers

30

Versions of IE before IE9 don't have an .indexOf() function for Array, to define the exact spec version, run this before trying to use it:

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

This is the version from MDN, used in Firefox/SpiderMonkey. In other cases such as IE, it'll add .indexOf() in the case it's missing... basically IE8 or below at this point.

Tuesday, June 1, 2021
 
Terry
answered 7 Months ago
43

The main difference between an array and an arraylist is that an arraylist is a class that is written in Java and has its own implementation (including the decision to override toString) whereas arrays are part of the language specification itself. In particular, the JLS 10.7 states:

The members of an array type are all of the following:

  • The public final field length
  • The public method clone, which overrides the method of the same name in class Object and throws no checked exceptions.
  • All the members inherited from class Object; the only method of Object that is not inherited is its clone method.

In other words the language specification prevents the toString method of an array to be overriden and it therefore uses the default implementation defined in Object which prints the class name and hashcode.

Why this decision has been made is a question that should probably be asked to the designers of the language...

Wednesday, July 28, 2021
 
Daveel
answered 5 Months ago
83

The variable 'top' used in the code is an object of type DispHTMLWindow2 (outermost window object) and already in use by the browsers and that is causing the conflict, as that object cant be the target of the assignment operation. It seems that Firefox and Safari ignore this, while IE does not allow scripts to overwrite this.

Solutions for this:

1) Declare top you are using as local variable to define it's scope where it is used.

2) Rename the variable to something that doesn't conflict with this predefined global.

Description of other variable names you shouldn't use

Saturday, October 9, 2021
 
Silver Light
answered 2 Months ago
24

You are not the first mixing up arrays and objects. SO should contain a FAQ for this kind of questions ;)

Let's try to explain things:

An array is a row of values, which can be retrieved using their position in the row. The order of the array values is fixed (and may be reordered).

An object is a variable that contains named properties in the form of key-value pairs. The order of the key-value pairs belonging to an object is arbitrary.

An array looks like: [ 'first', 'second', 'third', ..., 'nth' ]
An object looks like: { first:'firstvalue', second:'secondvalue', ..., nth:'nthvalue' }

The first element of an array is the element with index 0 (so the first position in the row has index value 0). You retrieve it using myArray[0]

An object is unordered, so it has no first element. You retrieve any element from it using myObject.somekey or myObject['somekey'].

For arrays you use a loop iterating through the numbered index until the end of the array is reached:

var i=0, len = myArray.length;
for ( i; i<len; i++ ) {
     //do something with >>> myArray[i] <<<
}

For objects you use a loop using the key and the in operator (making sure you are only retrieving user defined properties of the object with the .hasOwnAttribute method):

for ( var key in myObject ){
  if (myObject.hasOwnProperty(key)) {
     // do something with >>> myObject[key] <<<
  }
}

Basically, think of an array as a cupboard with drawers, each containing a value. An object can be imagined as a pile of boxes with stickers on the lid, describing the content of the box. Retrieving something from an object, you ask: is there a box with sticker y in pile x and if so, what's in it? Retrieving something from an array, you ask: please give me the contents of drawer nr x.

Now as to your question: the array you are retrieving values for with a for..in loop contains a user defined method, namely indexOf. Using the object style loop for it, the array is treated as object, and the indexOf key (with value like function(){...} I bet) is shown too. IE That's why it may be better to use a traditional for loop with a numeric index when iterating over arrays.

Why is this only in IE? In modern browsers indexOf is a native method of the Array prototype, and native methods are not shown (unless you loop through their prototype that is). IE < 9 doesn't have a native indexOf method for arrays. Somewhere in the scripting you use the method has been added to the Array prototype as a user defined extension.

Bottom line for your problem: don't use for ... in to loop through the values of an array.

Monday, October 25, 2021
 
Gabriele
answered 1 Month ago
12
  1. If they both have the same length, indexes, and values how is one iterable but the other isn't?

These functions are explicitly documented to perform this way. Both arrays are iteratable, but forEach/map/etc explicitly skips indices which are not in the array:

var sparse = new Array(3);
var dense = Array.apply(null, Array(3)); // See dense array link belo

1 in sparse; // false
1 in dense; // true

// Sparse can still be iterated over
sparse[100] = 'a'
sparse.forEach(function (n, i) { console.log(n, i) }); // a 100
  1. What is the reason for the difference?

Presumably an explicit decision was made to omit indices which don't exist

  1. What is the best way to determine if an array is sparse or dense?

You can use the following:

function isSparse(array) {
  for (var i = 0; i < array.length; ++i) {
    if (!i in array)
      return true;
  return false;
}

RE: Your comment

There has got be a reason for why [,,,] doesn't have indexes but [undefined, undefined, undefined] does.

There doesn't have to be a reason, that's just the way they're built. One has keys, the other doesn't.

Look:

Object.keys(Array(3)) // => []
Object.keys(['a','b']) // => ["0", "1"]
Monday, November 8, 2021
 
Extrakun
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share