Prototype JavaScript framework

class Array

Description

Prototype extends all native JavaScript arrays with quite a few powerful methods.

This is done in two ways:

  • It mixes in the Enumerable module, which brings a ton of methods in already.
  • It adds quite a few extra methods, which are documented in this section.

With Prototype, arrays become much, much more than the trivial objects we used to manipulate, limiting ourselves to using their length property and their [] indexing operator. They become very powerful objects that greatly simplify the code for 99% of the common use cases involving them.

Why you should stop using for…in to iterate

Many JavaScript authors have been misled into using the for…in JavaScript construct to loop over array elements. This kind of code just won’t work with Prototype.

The ECMA 262 standard, which defines ECMAScript 3rd edition, supposedly implemented by all major browsers including MSIE, defines ten methods on Array (§15.4.4), including nice methods like concat, join, pop, and push.

This same standard explicitely defines that the for…in construct (§12.6.4) exists to enumerate the properties of the object appearing on the right side of the in keyword. Only properties specifically marked as non-enumerable are ignored by such a loop. By default, the prototype and length properties are so marked, which prevents you from enumerating over array methods when using for…in. This comfort led developers to use for…in as a shortcut for indexing loops, when it is not its actual purpose.

However, Prototype has no way to mark the methods it adds to Array.prototype as non-enumerable. Therefore, using for…in on arrays when using Prototype will enumerate all extended methods as well, such as those coming from the Enumerable module, and those Prototype puts in the Array namespace (listed further below).

What you should use instead

You can revert to vanilla loops:

for (var index = 0; index < myArray.length; ++index) {
  var item = myArray[index];
  // Your code working on item here...
}

Or you can use iterators, such as Array#each:

myArray.each(function(item) {
  // Your code working on item here...
});

The inability to use for...in on arrays is not much of a burden: as you’ll see, most of what you used to loop over arrays for can be concisely done using the new methods provided by Array or the mixed-in Enumerable module. So manual loops should be fairly rare.

A note on performance

Should you have a very large array, using iterators with lexical closures (anonymous functions that you pass to the iterators and that get invoked at every loop iteration) in methods like Array#each — or relying on repetitive array construction (such as uniq), may yield unsatisfactory performance. In such cases, you’re better off writing manual indexing loops, but take care then to cache the length property and use the prefix ++ operator:

// Custom loop with cached length property: maximum full-loop
// performance on very large arrays!
for (var index = 0, len = myArray.length; index < len; ++index) {
  var item = myArray[index];
  // Your code working on item here...
}

Related utilities

$A, $w

Instance methods

  • clear

    Array#clear() -> Array

    Empties an array.

  • clone

    Array#clone() -> Array

    Returns a duplicate of the array, leaving the original array intact.

    Alias of:

  • compact

    Array#compact() -> Array

    Trims the array of null, undefined, or other "falsy" values.

  • first

    Array#first() -> ?

    Returns the array's first item.

  • flatten

    Array#flatten() -> Array

    Returns a “flat” (one-dimensional) version of the array.

    Nested arrays are recursively injected “inline”. This can prove very useful when handling the results of a recursive collection algorithm, for instance.

  • indexOf

    Array#indexOf(item[, offset = 0]) -> Number
    • item (?) – A value that may or may not be in the array.
    • offset (Number) – The number of initial items to skip before beginning the search.

    Returns the position of the first occurrence of item within the array — or -1 if item doesn’t exist in the array.

  • inspect

    Array#inspect() -> String

    Returns the debug-oriented string representation of an array.

  • intersect

    Array#intersect(array) -> Array
    • array (Array) – A collection of values.

    Returns an array containing every item that is shared between the two given arrays.

  • last

    Array#last() -> ?

    Returns the array's last item.

  • lastIndexOf

    Array#lastIndexOf(item[, offset]) -> Number
    • item (?) – A value that may or may not be in the array.
    • offset (Number) – The number of items at the end to skip before beginning the search.

    Returns the position of the last occurrence of item within the array — or -1 if item doesn’t exist in the array.

  • reduce

    Array#reduce() -> Array

    Reduces arrays: one-element arrays are turned into their unique item, while multiple-element arrays are returned untouched.

  • reverse

    Array#reverse([inline = false]) -> Array
    • inline (Boolean) – Whether to modify the array in place. If false, clones the original array first.

    Returns the reversed version of the array.

  • size

    Array#size() -> Number

    Returns the size of the array.

    This is just a local optimization of the mixed-in Enumerable#size which avoids array cloning and uses the array’s native length property.

  • toJSON

    Array#toJSON() -> String

    Returns a JSON string representation of the array.

  • uniq

    Array#uniq([sorted = false]) -> Array
    • sorted (Boolean) – Whether the array has already been sorted. If true, a less-costly algorithm will be used.

    Produces a duplicate-free version of an array. If no duplicates are found, the original array is returned.

  • without

    Array#without(value...) -> Array
    • value (?) – A value to exclude.

    Produces a new version of the array that does not contain any of the specified values.

Class methods

  • from

    Array.from(iterable) -> Array

    Aliased as: $A

    Alias of: $A