Je m’amusais avec JavaScript et j’ai remarqué que this
ne pouvait jamais être une primitive. De quoi est-ce que je parle? Laisse-moi expliquer.
Prenez cette fonction par exemple.
function test(){ return typeof this; } test.call('Abc'); // 'object' test.call(123); // 'object'
Ils sont tous 'object'
deux 'object'
, pas 'ssortingng'
ou 'number'
, comme je m’y attendais.
Après un peu de confusion (et de jouer avec instanceof
), j’ai compris ce qui se passait. 'Abc'
est converti en object Ssortingng
et 123
est converti en object Number
.
Quoi qu’il en soit, ma question est la suivante: pourquoi cela se produit-il et comment puis-je reconvertir un object en primitif?
Je sais que je pourrais utiliser (Ssortingng)this
ou (Number)this
, mais comment puis-je le faire si je ne connais pas le type?
EDIT : J’essayais de faire ceci:
function element(){ var $e = $(this), $d = $e.closest('div'); } element.call('#myID');
et ça ne marchait pas. this
s’agit d’un object Ssortingng
et jQuery a simplement créé une collection d’objects au lieu d’utiliser le sélecteur pour effectuer une recherche dans le DOM.
Comme d’autres l’ont noté, il est contraint de placer un object conformément à la spécification.
La chose importante à noter est que si vous êtes en mode ssortingct , la contrainte ne se produit pas.
"use ssortingct"; function test(){ return typeof this; } test.call('Abc'); // 'ssortingng' test.call(123); // 'number'
La vraie question est donc pourquoi vous n’utilisez pas ssortingct ? 😉
Comme vous l’avez noté dans votre commentaire, vous devriez pouvoir utiliser .valueOf()
si vous prenez en charge des implémentations qui ne prennent pas en charge le mode ssortingct.
Si vous attendez seulement une chaîne, ou si vous attendez également un nombre, mais que cela ne vous dérange pas pour une chaîne numérique, vous pouvez le faire …
(this + '') // "Abc" (this + '') // "123"
“mais comment puis-je faire cela si je ne connais pas le type”
Si vous souhaitez connaître son type, utilisez le toSsortingng
générique disponible sur Object.prototype
pour obtenir la propriété interne [[Class]] .
Object.prototype.toSsortingng.call( this ); "[object Ssortingng]" Object.prototype.toSsortingng.call( this ); "[object Number]"
Je l’ai trouvé, ECMAScript 5.1
REMARQUE La valeur thisArg est transmise sans modification en tant que valeur
this
. Il s’agit d’une modification par rapport à l’édition 3, dans laquelle thisArg,undefined
ounull
est remplacé par l’object global etToObject
est appliqué à toutes les autres valeurs et ce résultat est transmis sous la forme dethis
valeur.
Fondamentalement, il est indiqué que le premier paramètre est undefined
et null
car this
s’agit de l’object global ( window
dans un contexte de navigateur), et toutes les autres valeurs sont converties en object à l’aide de ToObject
.
En raison des incohérences de typeof
, je recommande d’utiliser Object.prototype.toSsortingng.call
, qui renvoie des valeurs cohérentes dans tous les navigateurs que j’ai testés:
Object.prototype.toSsortingng.call('foo') //[object Ssortingng] Object.prototype.toSsortingng.call(10000) //[object Number] Object.prototype.toSsortingng.call(someFunc) //[object Function] ...etc
vous pouvez comparer la sortie dans ce violon
La spécification dit qu’il s’agit toujours d’un object.
Sinon, si Type (thisArg) n’est pas Object, définissez ThisBinding sur ToObject (thisArg).
D’après ce que je comprends, this
n’a aucun sens en dehors d’un contexte orienté object, il s’agira toujours de pointer sur l’instance d’un object. Donc, par définition, cela ne peut pas être une primitive.
En outre, il semble que votre fonction de test renvoie le typeof
la fonction de test
elle-même (ce qui est dans ce contexte), et non les parameters que vous transmettez.