Question

Je suis en train de parcourir l'excellent didacticiel JavaScript avancé de John Resig et je ne comprends pas très bien ce qu'il en est. la différence entre les appels suivants: (veuillez noter que 'arguments' est un mot javascript intégré et qu'il ne s'agit pas exactement d'un tableau, d'où le piratage avec Array.slice au lieu d'appeler simplement arguments.slice)

>>> arguments  
[3, 1, 2, 3]  
>>> Array.slice.call( arguments )  
3,1,2,3 0=3 1=1 2=2 3=3  
>>> Array.slice.call( arguments, 1 )  
[]
>>> Array().slice.call( arguments )  
3,1,2,3 0=3 1=1 2=2 3=3  
>>> Array().slice.call( arguments, 1 )  
1,2,3 0=1 1=2 2=3  

En gros, mon incompréhension se résume à la différence entre Array.slice et Array (). slice. Quelle est exactement la différence entre ces deux et pourquoi Array.slice.call ne se comporte pas comme prévu? (qui restitue tous les éléments sauf le premier élément de la liste des arguments).

Était-ce utile?

La solution

Pas tout à fait.

Regardez ce qui se passe lorsque vous appelez String.substring.call ("foo", 1) et String (). substring.call ("foo", 2):

>>> String.substring.call("foo", 1)
"1"

>>> String().substring.call("foo", 1)
"oo"

Array.slice n'est ni référençant correctement la fonction de tranche attachée au prototype Array, ni la fonction de tranche attachée à une instance Array instanciée (telle que Array () ou []).

Le fait que Array.slice soit même non nul est une implémentation incorrecte de l'objet (/ function / constructeur) lui-même. Essayez d'exécuter le code équivalent dans IE et vous obtiendrez une erreur indiquant que Array.slice est null .

C’est pourquoi Array.slice ne se comporte pas correctement (ni String.substring).

Démonstration (voici ce à quoi on ne devrait jamais s’attendre en se basant sur la définition de slice () ... tout comme pour substring () ci-dessus):

>>> Array.slice.call([1,2], [3,4])
3,4

Maintenant, si vous appelez correctement slice () sur un objet instancié ou sur le prototype Array, vous obtiendrez ce que vous attendez:

>>> Array.prototype.slice.call([4,5], 1)
[5]
>>> Array().slice.call([4,5], 1)
[5]

Plus de preuves ...

>>> Array.prototype.slice == Array().slice
true
>>> Array.slice == Array().slice
false

Autres conseils

Un tableau est juste une fonction, bien que spéciale (utilisée pour initialiser des tableaux). Array.slice est une référence à la fonction slice () dans le prototype Array. Il ne peut être appelé que sur un objet tableau et non sur le constructeur (c'est-à-dire le tableau) lui-même. Cependant, Array semble se comporter particulièrement bien, puisque Array () renvoie un tableau vide. Cela ne semble pas fonctionner pour les fonctions de constructeur non intégrées (vous devez utiliser new). Donc

Array().slice.call

est identique à

[].slice.call

Comment les appels à slice.call () fonctionnent-ils dans les exemples fournis puisqu'un paramètre de contexte n'est pas fourni? Est-ce que slice implémente sa propre méthode d'appel, écrasant ainsi la méthode d'appel de JavaScript? Les méthodes call et apply prennent en premier paramètre un objet pour spécifier l'objet context (this) à appliquer à l'appel.

Je pense que Array est le type et Array () est la fonction constructeur.

Déconner dans FireBug :

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()

Eh bien,

En regardant http://www.devguru.com/Technologies/ecmascript /quickref/slice.html

Array (). slice est une fonction (constructeur) de la classe array, elle ne peut pas être utilisée en tant que membre de données. Si vous ne voulez pas utiliser le '()', vous devez l'appeler sur le tableau. ie - arguments.slice (1)

Je suppose que Array est un prototype, alors que Array () est un objet de tableau. En fonction de l'interprétation JavaScript, l'appel direct de la méthode prototype d'un type d'objet intégré peut fonctionner ou non. Je ne crois pas que la spécification indique que cela doit fonctionner, mais simplement que l'appeler sur un objet instancié fonctionne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top