Array.prototype.slice()

La méthode slice() renvoie un objet tableau, contenant une copie superficielle (shallow copy) d'une portion du tableau d'origine.

Syntaxe

arr.slice(début[, fin])

Paramètres

début
Indice (à partir de zéro) depuis lequel commencer l'extraction.
S'il s'agit d'un indice négatif, début indique un décalage depuis la fin de la séquence. Par exemple, slice(-2) extrait les avant-dernier et dernier éléments dans la séquence.

Si début est omis, slice() commencera depuis 0.
fin
Indice (à partir de zéro) auquel arrêter l'extraction. slice() extrait jusqu'à cet indice, mais pas l'élément situé en fin lui-même.
slice(1,4) extrait du deuxième au quatrième élément (les éléments d'indices 1, 2 et 3).
S'il s'agit d'un indice négatif, fin indique un décalage depuis la fin de la séquence. slice(2,-1) extrait du troisième à l'avant-dernier élément dans la séquence.
Si fin n'est pas fourni, slice() extraira jusqu'à la fin de la séquence.

Description

slice() ne modifie pas le tableau original, mais renvoie une nouvelle copie du tableau (shallow copie) dont les éléments sont des copies des éléments extraits du tableau original. Les éléments du tableau original sont copiés dans le nouveau tableau de la manière suivante :

  • Pour les références à des objets (et non les objets eux-mêmes), slice() copie ces références dans le nouveau tableau. Tant l'original que le nouveau tableau font référence au même objet. Si un objet référencé est modifié, ces changements sont visibles tant pour le nouveau que pour l'ancien tableau.
  • Pour les chaines de caractères et les nombres (pas les objets String  et Number), slice() copie ces chaines de caractères et ces nombres dans le nouveau tableau. Les modifications sur ces chaînes ou nombres dans l'un des tableaux n'affectent pas l'autre tableau.

Si un nouvel élément est ajouté à l'un ou l'autre tableau, le second n'est pas affecté.

Exemples

Renvoyer un fragment d'un tableau existant

var fruits = ["Banane", "Orange", "Citron", "Pomme", "Mangue"];
var agrumes = fruits.slice(1, 3);

// agrumes vaut --> ["Orange", "Citron"]

Utiliser slice()

Dans l'exemple qui suit, slice() crée un nouveau tableau, nouvelleVoiture, à partir de maVoiture. Chacun d'entre eux contient une référence à l'objet maHonda. Lorsque la couleur de maHonda est changée en bordeaux, les deux tableaux reflètent ce changement.

// Avec slice, crée nouvelleVoiture depuis maVoiture
var maHonda = { couleur : "rouge", roues : 4, moteur : { cylindres : 4, capacité : 2.2 } };
var maVoiture = [maHonda, 2, "excellente condition", "achetée en 1997"];
var nouvelleVoiture = maVoiture.slice(0, 2);

// Affiche les valeurs de maVoiture, nouvelleVoiture et la couleur de maHonda
// référencées depuis chacun des tableaux.
console.log("maVoiture = " + maVoiture.toSource());
console.log("nouvelleVoiture = " + nouvelleVoiture.toSource());
console.log("maVoiture[0].couleur = " + maVoiture[0].couleur);
console.log("nouvelleVoiture[0].couleur = " + nouvelleVoiture[0].couleur);

// Change la couleur de maHonda.
maHonda.couleur = "bordeaux";
console.log("La nouvelle couleur de ma Honda est " + maHonda.couleur);

// Affiche la couleur de maHonda référencées depuis les deux tableaux.
console.log("maVoiture[0].couleur = " + maVoiture[0].couleur);
console.log("nouvelleVoiture[0].couleur = " + nouvelleVoiture[0].couleur);

Ce script affichera :

maVoiture = [{couleur:"red", roues:4, moteur:{cylindres:4, capacité:2.2}}, 2,
             "excellente condition", "achetée en 1997"]
nouvelleVoiture = [{couleur:"rouge", roues:4, moteur:{cylindres:4, capacité:2.2}}, 2]
maVoiture[0].couleur = rouge
nouvelleVoiture[0].couleur = rouge
La nouvelle couleur de ma Honda est bordeaux
maVoiture[0].couleur = bordeaux
nouvelleVoiture[0].couleur = bordeaux

Utilisation avec les objets similaires aux tableaux

La méthode slice() peut aussi être appelée pour convertir des objets/collections similaires à des tableaux, en un nouveau tableau. L'objet arguments d'une fonction est un exemple d'objet similaire à un tableau.

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

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

Il est possible de lier avec la fonction .call de Function.prototype et on peut effectuer la réduction avec [].slice.call(arguments) plutôt qu'avec Array.prototype.slice.call. Voici comment on peut simplifier avec 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]

Homogénéiser le comportement entre navigateurs

Pour les objets de l'environnement (tels que les objets du DOM), il n'est pas strictement nécessaire que la conversion effectuée par Array.prototype.slice soit effectuée de la même façon que décrite précédemment (hors spécification). Cependant l'ensemble des navigateurs (IE, Mozilla, Chrome, Safari et Opera), à l'exception des versions IE < 9 fonctionne de la même façon. Il est donc possible d'utiiser ce standard de fait pour construire un « shim » qui permettent d'utiliser ce comportement pour tous les navigateurs. Le code qui suit permet également de corriger le comportement d'IE < 9 lorsque le second argument de slice() est null ou undefined :

/**
 * Shim permettant de corriger le support IE < 9 lors de l'application
 * de splice pour les objets de l'environnement comme NamedNodeMap,
 * NodeList, and HTMLCollection (bien que, techniquement, le comportement des
 * objets de l'environnement est laissé à l'implémentation et n'est pas
 * spécifié en tant que tel, au moins avant ES6)
 * Fonctionne également sur les chaîne et corrige le comportement IE < 9
 * lorsque la méthode utilise undefined comme second argument. On empêche
 * également des erreurs d'appels sur d'autres objets DOM.
 */
(function () {
  'use strict';
  var _slice = Array.prototype.slice;

  try {
    // Ne pourra pas être utilisé avec les éléments du DOM pour IE < 9
    _slice.call(document.documentElement);
  } catch (e) { // Échouera avec IE < 9
    // Le code qui suit fonctionnera pour les tableaux (Array), les objets
    // semblables aux tableaux,  
    // NamedNodeMap (attributs, entités, notations),
    // NodeList (ex. : getElementsByTagName), HTMLCollection (ex: childNodes),
    // et n'échouera pas sur les autres objets DOM
    Array.prototype.slice = function(begin, end) {
      // IE < 9 ne fonctionne pas avec undefined
      end = (typeof end !== 'undefined') ? end : this.length;

      // Pour les objets Array natifs, on utilise la fonction native
      if (Object.prototype.toString.call(this) === '[object Array]'){
        return _slice.call(this, begin, end);
      }

      // Pour les objets *semblables* aux tableau
      // on code le comportement
      var i, cloned = [],
        size, len = this.length;

      // On gère les valeurs négatives pour "begin"
      var start = begin || 0;
      start = (start >= 0) ? start: Math.max(0, len + start);

      // On gère les valeurs négatives pour "end"
      var upTo = (typeof end == 'number') ? Math.min(end, len) : len;
      if (end < 0) {
        upTo = len + end;
      }

      // Taille réelle de la "tranche"
      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;
    };
  }
}());

Spécifications

Spécification Statut Commentaires
ECMAScript 3rd Edition (ECMA-262) Standard Définition initiale. Implémentée avec JavaScript 1.2.
ECMAScript 5.1 (ECMA-262)
La définition de 'Array.prototype.slice' dans cette spécification.
Standard  
ECMAScript 2015 (6th Edition, ECMA-262)
La définition de 'Array.prototype.slice' dans cette spécification.
Standard  

Compatibilité des navigateurs

Fonctionnalité Chrome Firefox (Gecko) Internet Explorer Opera Safari
Support simple 1.0 1.0 (1.7 ou moins) (Oui) (Oui) (Oui)
Fonctionnalité Android Chrome pour Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Support simple (Oui) (Oui) (Oui) (Oui) (Oui) (Oui)

Voir aussi

Étiquettes et contributeurs liés au document

Contributeurs à cette page : SphinxKnight, teoli, tregagnon, Jeremie, BenoitL
Dernière mise à jour par : SphinxKnight,
Masquer la barre latérale