Je sais qu'il est utilisé pour faire des arguments un vrai tableau, mais je ne comprends pas ce qui se passe lors de l'utilisation Array.prototype.slice.call(arguments)
474
Je sais qu'il est utilisé pour faire des arguments un vrai tableau, mais je ne comprends pas ce qui se passe lors de l'utilisation Array.prototype.slice.call(arguments)
Réponses:
Ce qui se passe sous le capot, c'est que lorsqu'il
.slice()
est appelé normalement,this
est un tableau, puis il itère simplement sur ce tableau et fait son travail.Comment est
this
dans la.slice()
fonction un tableau? Parce que quand vous le faites:... le
object
devient automatiquement la valeur dethis
dans lemethod()
. Donc avec:... le
[1,2,3]
tableau est défini comme la valeur dethis
in.slice()
.Mais que se passe-t-il si vous pouvez remplacer quelque chose d'autre par la
this
valeur? Tant que tout ce que vous remplacez a une.length
propriété numérique et un tas de propriétés qui sont des indices numériques, cela devrait fonctionner. Ce type d'objet est souvent appelé objet de type tableau .Les méthodes
.call()
et.apply()
vous permettent de définir manuellement la valeur dethis
dans une fonction. Donc, si nous définissons la valeur dethis
in.slice()
dans un objet de type tableau , supposerons.slice()
simplement qu'il fonctionne avec un tableau et fera son travail.Prenez cet objet simple comme exemple.
Ce n'est évidemment pas un tableau, mais si vous pouvez le définir comme
this
valeur de.slice()
, cela fonctionnera simplement, car il ressemble suffisamment à un tableau pour.slice()
fonctionner correctement.Exemple: http://jsfiddle.net/wSvkv/
Comme vous pouvez le voir dans la console, le résultat est ce que nous attendons:
C'est donc ce qui se produit lorsque vous définissez un
arguments
objet commethis
valeur de.slice()
. Parce qu'ilarguments
a une.length
propriété et un tas d'index numériques,.slice()
va juste sur son travail comme s'il travaillait sur un vrai tableau.la source
Array.prototype.slice
description de la méthode.for-in
déclaration qui ne garantit pas l'ordre. L'algorithme utilisé par.slice()
définit un ordre numérique commençant par0
et se terminant (non inclus) par l'.length
objet donné (ou Array ou autre). Il est donc garanti que l'ordre est cohérent dans toutes les implémentations.var obj = {2:"two", 0:"zero", 1: "one"}
. Si nous utilisonsfor-in
pour énumérer l'objet, il n'y a aucune garantie d'ordre. Mais si nous utilisonsfor
, nous pouvons appliquer manuellement l'ordre:for (var i = 0; i < 3; i++) { console.log(obj[i]); }
. Nous savons maintenant que les propriétés de l'objet seront atteintes dans l'ordre numérique croissant que nous avons défini par notrefor
boucle. Voilà ce qui.slice()
fait. Il ne se soucie pas d'avoir un véritable tableau. Il commence juste à0
et accède aux propriétés dans une boucle ascendante.L'
arguments
objet n'est pas réellement une instance d'un tableau et n'a aucune des méthodes de tableau. Donc,arguments.slice(...)
cela ne fonctionnera pas car l'objet arguments n'a pas la méthode slice.Les tableaux ont cette méthode, et parce que l'
arguments
objet est très similaire à un tableau, les deux sont compatibles. Cela signifie que nous pouvons utiliser des méthodes de tableau avec l'objet arguments. Et puisque les méthodes de tableau ont été construites avec des tableaux à l'esprit, elles renverront des tableaux plutôt que d'autres objets d'argument.Alors pourquoi l'utiliser
Array.prototype
? C'estArray
l'objet à partir duquel nous créons de nouveaux tableaux à partir de (new Array()
), et ces nouveaux tableaux sont des méthodes et des propriétés transmises, comme slice. Ces méthodes sont stockées dans l'[Class].prototype
objet. Donc, pour des raisons d'efficacité, au lieu d'accéder à la méthode de tranche par(new Array()).slice.call()
ou[].slice.call()
, nous l'obtenons directement à partir du prototype. C'est ainsi que nous n'avons pas à initialiser un nouveau tableau.Mais pourquoi devons-nous le faire en premier lieu? Eh bien, comme vous l'avez dit, il convertit un objet arguments en une instance Array. Cependant, la raison pour laquelle nous utilisons la tranche est plus un "hack" qu'autre chose. La méthode slice prendra une, vous l'avez deviné, une tranche d'un tableau et retournera cette tranche comme un nouveau tableau. Le fait de ne lui passer aucun argument (en plus de l'objet arguments comme contexte) amène la méthode slice à prendre un morceau complet du "tableau" passé (dans ce cas, l'objet arguments) et à le renvoyer comme un nouveau tableau.
la source
Normalement, appeler
copiera le tableau
a
dansb
. Cependant, nous ne pouvons pas fairecar
arguments
n'est pas un vrai tableau et n'a passlice
de méthode.Array.prototype.slice
est laslice
fonction des tableaux etcall
exécute la fonction avec la valeurthis
setarguments
.la source
prototype
? n'est passlice
uneArray
méthode native ?Array
s'agit d'une fonction constructeur et que la "classe" correspondante estArray.prototype
. Vous pouvez également utiliser[].slice
slice
est une méthode de chaqueArray
instance, mais pas laArray
fonction constructeur. Vous utilisezprototype
pour accéder aux méthodes des instances théoriques d'un constructeur.Tout d'abord, vous devriez lire comment fonctionne l'invocation de fonctions en JavaScript . Je soupçonne que cela suffit à lui seul pour répondre à votre question. Mais voici un résumé de ce qui se passe:
Array.prototype.slice
extrait la méthode de de » prototype . Mais l'appeler directement ne fonctionnera pas, car c'est une méthode (pas une fonction) et nécessite donc un contexte (un objet appelant ), sinon il lancerait .slice
Array
this
Uncaught TypeError: Array.prototype.slice called on null or undefined
La
call()
méthode vous permet de spécifier le contexte d'une méthode, ce qui rend essentiellement ces deux appels équivalents:Sauf que le premier nécessite que la
slice
méthode existe danssomeObject
la chaîne de prototypes de (comme il le fait pourArray
), tandis que le second permet au contexte (someObject
) d'être passé manuellement à la méthode.En outre, ce dernier est l'abréviation de:
C'est la même chose que:
la source
la source
Array.prototype.slice.call (arguments) est la méthode à l'ancienne pour convertir un argument en tableau.
Dans ECMAScript 2015, vous pouvez utiliser Array.from ou l'opérateur de propagation:
la source
C'est parce que, comme le note MDN
Ici, nous faisons appel
slice
à l'objet natifArray
et non à sa mise en œuvre et c'est pourquoi le supplément.prototype
la source
N'oubliez pas, qu'une base basique de ce comportement est la fonte de type qui s'est entièrement intégrée au moteur JS.
Slice prend simplement l'objet (grâce à la propriété arguments.length existante) et retourne le tableau-objet casté après avoir fait toutes les opérations dessus.
Les mêmes logiques que vous pouvez tester si vous essayez de traiter la méthode String avec une valeur INT:
Et cela explique la déclaration ci-dessus.
la source
Il utilise les
slice
tableaux méthode ont et appelle sonthis
être l'arguments
objet. Cela signifie qu'il l'appelle comme si vous supposiezarguments.slice()
qu'ilarguments
avait une telle méthode.La création d'une tranche sans argument prendra simplement tous les éléments - elle copie donc simplement les éléments de
arguments
dans un tableau.la source
Supposons que vous ayez:
function.apply(thisArg, argArray )
La méthode slice () sélectionne une partie d'un tableau et renvoie le nouveau tableau.
Ainsi, lorsque vous appelez
Array.prototype.slice.apply(arguments, [0])
la méthode de tranche de tableau est invoquée (bind) sur les arguments.la source
Peut-être un peu tard, mais la réponse à tout ce gâchis est que call () est utilisé dans JS pour l'héritage. Si nous comparons cela à Python ou PHP, par exemple, call est utilisé respectivement comme super (). init () ou parent :: _ construct ().
Ceci est un exemple de son utilisation qui clarifie tout:
Référence: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance
la source
lorsque .slice () est appelé normalement, il s'agit d'un tableau, puis il itère simplement sur ce tableau et fait son travail.
la source
J'écris juste ceci pour me rappeler ...
Ou utilisez simplement cette fonction pratique $ A pour transformer la plupart des choses en un tableau.
exemple d'utilisation ...
la source