Array.prototype.slice()

El m茅todo slice() devuelve una copia de una parte del array dentro de un nuevo array empezando por inicio hasta fin (fin no incluido). El array original no se modificar谩.

El c贸digo fuente de esta demostraci贸n interactiva est谩 alojado en un repositorio Github. Si desea contribuir con ella, por favor clone https://github.com/mdn/interactive-examples y env铆enos un "pull request".

Sintaxis 

arr.slice([inicio [, fin]])

Par谩metros

inicio
脥ndice donde empieza la extracci贸n. El primer elemento corresponde con el 铆ndice  0.
Si el 铆ndice especificado es negativo, indica un desplazamiento desde el final del array. slice(-2)extrae los dos 煤ltimos elementos del array
Si inicio es omitido el valor por defecto es 0.
Si inicio es mayor a la longitud del array, se devuelve un array vac铆o.
fin
脥ndice  que marca el final de la extracci贸n. slice extrae hasta, pero sin incluir el final.
slice(1,4) extrae desde el segundo elemento hasta el cuarto  (los elementos con 铆ndices 1, 2,  y 3).
Con un 铆ndice negativo, fin indica un desplazamiento desde el final de la secuencia. slice(2,-1) extrae desde el tercer hasta el pen煤ltimo elemento en la secuencia.
Si fin es omitido, slice extrae hasta el final de la secuencia (arr.length).
Si fin es mayor a la longitud del array, slice extrae hasta el final de la secuencia (arr.length).

Valor de retorno

Un nuevo array con los valores extra铆dos.

Descripci贸n

slice no modifica el array original. Devuelve una copia plana (shallow copy) de los elementos especificados del array original. Los elementos del array original son copiados en el array devuelto de la siguiente manera:

  • Para referencias de objeto ( no el objeto en s铆 ), slice copia la referencia dentro del nuevo array. Ambos, el array original y el nuevo, referencian al mismo objeto. Si un objeto referenciado cambia, los cambios son visibles para ambos arrays.
  • Para strings, numbers y boolean (no objetos StringNumber), slice copia los valores en el nuevo array. Los cambios a los string, numbers y boolean en un array no afectan a los del otro array.

Si un nuevo elemento es agregado a cualquiera de los arrays, el otro array no es afectado.

Ejemplos

Ejemplo: Devolver una porci贸n de un array existente

var nombres = ['Rita', 'Pedro', 'Miguel', 'Ana', 'Vanesa'];
var masculinos = nombres.slice(1, 3);

// masculinos contiene ['Pedro','Miguel']

Ejemplo: Utilizando slice

Presta especial atenci贸n a:

  • Valores de tipos b谩sicos, como string o number, son copiados al nuevo array. Cambiar estos valores en la copia no afecta al array original.
  • Las referencias tambi茅n se copian. Mismas referencias acceden al mismo objeto destino. Cambios en el objeto destino son compartidos por todos sus accesos.

En el siguiente ejemplo, slice crea un nuevo array, nuevoCoche, de myCoche. Los dos incluyen una referncia al objecto miHonda se cambia a p煤rpura, ambas matrices reflejan el cambio.

var miHonda = { color: 'red', ruedas: 4, motor: { cilindros: 4, cantidad: 2.2 } };
var miCoche = [miHonda, 2, 'Buen estado', 'comprado 1997'];
var nuevoCoche = miCoche.slice(0, 2);

//  Muestra los valores de myCar, newCar y el color de myHonda.
console.log('miCoche = ' + JSON.stringify(miCoche));
console.log('nuevoCoche = ' + JSON.stringify(nuevoCoche));
console.log('miCoche[0].color = ' + miCoche[0].color);
console.log('nuevoCoche[0].color = ' + nuevoCoche[0].color);

// Cambia el color de miHonda.
miHonda.color = 'azul';
console.log('El nuevo color de mi Honda es ' + miHonda.color);

// Muestra el color de myHonda referenciado desde ambos arrays. 
console.log('miCoche[0].color = ' + miCoche[0].color);

console.log('nuevoCoche[0].color = ' + nuevoCoche[0].color);

Este script escribe:

miCoche = [{color: 'rojo', ruedas: 4, motor: {cilindros: 4, cantidad: 2.2}}, 2,
         'buen estado', 'comprado 1997']
nuevoCoche = [{color: 'rojo', ruedas: 4, motor: {cilindros: 4, cantidad: 2.2}}, 2]
miCoche[0].color = rojo
nuevoCoche[0].color = rojo
El nuevo color de miHonda es azul
miCoche[0].color = azul
nuevoCoche[0].color = azul

Objetos array-like

Se dice que un objeto es array-like ( similar o que se asemeja a un array) cuando entre sus propiedades existen algunas cuyos nombres son n煤meros y en particular tiene una propiedad llamada length. Este hecho  hace  suponer que el objeto es alg煤n tipo de colecci贸n de elementos indexados por n煤meros. Es conveniente, a veces, convertir estos objetos a arrays para otorgarles la funcionalidad que de serie se incorpora en todos los arrays a trav茅s de su prototipo. 

El m茅todo slice puede ser usado para convertir objetos parecidos a arrays o colecciones a un nuevo Array. Simplemente debe enlazar el m茅todo al objeto. El  arguments (en-US) dentro de una funci贸n es un ejemplo de un objeto parecido a arrays.

function list() {
  return Array.prototype.slice.call(arguments, 0);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

El enlazado puede realizarse con la funci贸n .call de  Function.prototype (en-US) y puede ser abreviado tambi茅n usando  [].slice.call(arguments) en lugar de Array.prototype.slice.call. En cualquier caso, puede ser simplificado usando bind.

var unboundSlice = Array.prototype.slice;
var slice = Function.prototype.call.bind(unboundSlice);

function list() {
  return slice(arguments, 0);
}

var list1 = list(1, 2, 3); // [1, 2, 3]

Coordinaci贸n del comportamiento entre navegadores

 

La especificaci贸n permite a los objetos del host  ( entre ellos los objetos del DOM )  ser dependientes de la implementaci贸n.  Esta NO obligatoriedad, origina diferencias en el comportamiento entre aquellos comprometidos con los est谩ndares, como Mozilla, y los que no. En lo que concierne a  Array.prototype.slice , por lo tanto, existen importantes incompatibilidades en IE < 9 . Versiones de IE a partir de la 9 permiten un comportamiento compatible m谩s fiable.  Se puede recurrir al  鈥shimming鈥  para alcanzar la compatibilidad en otros casos.  Mientras otros navegadores modernos contin煤an mejorando para soportar esta habilidad, en la forma en que actualmente lo hacen Mozilla, Chrome, Safari, Opera  e IE, los desarrolladores de c贸digo preocupados por el soporte DOM que conf铆en en este shim no deben dejarse enga帽ar por la sem谩ntica, deben confiar de forma segura en ella para proporcionar el comportamiento est谩ndar que aparentemente ahora es la norma.

El shim tambi茅n soluciona que IE pueda tratar con el caso de que el segundo argumento de slice() pueda ser un valor null/undefined expl铆cito. Esto era un problema en versiones anteriores de IE, pero todos los navegadores modernos, inclu铆do IE >= 9, lo hacen actualmente.

/**
 * Shim para "solucionar" la falta de soporte de IE (IE < 9) para aplicar slice
 * sobre objetos del host, tal como NamedNodeMap, NodeList, y HTMLCollection
 * (t茅cnicamente, al ser los objetos del host dependientes de la implementaci贸n,
 * al menos anteriormente a ES2015, IE no ten铆a la necesidad de trabajar de este modo).
 * Tambi茅n funciona sobre strings, solucionando que IE < 9 admita un undefined expl铆cito
 * como segundo argumento (igual que en Firefox), y previniendo errores cuando se llama
 * sobre otros objetos del DOM.
 */
(function () {
  'use strict';
  var _slice = Array.prototype.slice;

  try {
    // Fallar谩 al usarse con elementos DOM en IE < 9
    _slice.call(document.documentElement);
  } catch (e) { // Fails in IE < 9
    // Funcionar谩 con arrays genuinos, objetos array-like,
    // NamedNodeMap (attributes, entities, notations),
    // NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes),
    // and will not fail on other DOM objects (as do DOM elements in IE < 9)
    Array.prototype.slice = function(begin, end) {
      // A IE < 9 no le gustan los undefined como argumento end.
      end = (typeof end !== 'undefined') ? end : this.length;

      // Con objetos Array nativos, podemos usar la funci贸n slice
      if (Object.prototype.toString.call(this) === '[object Array]'){
        return _slice.call(this, begin, end);
      }

      // Con objetos array-like debemos manejarlo por nuestra cuenta.
      var i, cloned = [],
        size, len = this.length;

      // Maneja valores negativos para el argumento "inicio"
      var start = begin || 0;
      start = (start >= 0) ? start : Math.max(0, len + start);

      // Maneja valores negativos para el argumento "fin"
      var upTo = (typeof end == 'number') ? Math.min(end, len) : len;
      if (end < 0) {
        upTo = len + end;
      }

      // Tama帽o esperado para el slice
      size = upTo - start;

      if (size > 0) {
        cloned = new Array(size);
        if (this.charAt) {
          for (i = 0; i < size; i++) {
            cloned[i] = this.charAt(start + i);
          }
        } else {
          for (i = 0; i < size; i++) {
            cloned[i] = this[start + i];
          }
        }
      }

      return cloned;
    };
  }
}());

Especificaciones

Especificaci贸n Estado Observaciones
ECMAScript 3陋 edici贸n Estandar Definici贸n inicial Implementado en JavaScript 1.2.
ECMAScript 5.1 (ECMA-262)
La definici贸n de 'Array.prototype.slice' en esta especificaci贸n.
Standard  
ECMAScript 2015 (6th Edition, ECMA-262)
La definici贸n de 'Array.prototype.slice' en esta especificaci贸n.
Standard  

Compatibilidad con navegadores

La tabla de compatibilidad en esta p谩gina esta generada desde datos estructurados. Si desea contribuir con los datos, por favor "checkout" https://github.com/mdn/browser-compat-data  y env铆enos un "pull request".

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help! (en-US)
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Soporte b谩sico 1.0 1.0 (1.7 o anterior) (Yes) (Yes) (Yes)
Feature Android Chrome para Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Soporte b谩sico (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)

Ver tambi茅n