The trouble is that arrays must look and act like objects. Objects must look and at like hashes, and hashes are very inefficient. The solution is to implement arrays as arrays or structs and objects as structs or static classes. This sounds good, but what happens when that array changes size or a property is added to that object?
The answer is that the jit must constantly check for this behavior. If it sees this happen, it has to throw out all the optimized code it has generated and start over again (reducing performance in the meantime and using more power on mobile as well).
If the object cannot be changed, then the compiler can make more guarantees, so it can optimize sooner, more reliably, and is less likely to need to fall back to unoptimized byte code.