Principes de base
Vous ne le savez peut-être pas mais, en JavaScript, chaque fois que nous interagissons avec des primitives de type chaîne, nombre ou booléen, nous entrons dans un monde caché d'ombres d'objets et de coercition.
chaîne de caractères, nombre, booléen, null, indéfini et symbole.
En JavaScript, il existe 7 types de primitives : undefined
, null
, boolean
, string
, number
, bigint
y symbol
. Tout le reste est un objet. Les types primitifs boolean
, string
y number
peuvent être enveloppés par leurs homologues objets. Ces objets sont des instances de la classe Boolean
, String
y Number
respectivement.
typeof true; //"boolean"
typeof new Boolean(true); //"object"
typeof "this is a string"; //"string"
typeof new String("this is a string"); //"object"
typeof 123; //"number"
typeof new Number(123); //"object"
Si les primitives n'ont pas de propriétés, pourquoi "this is a string".length
retourner une valeur ?
Parce que JavaScript fait facilement la distinction entre primitives et objets. Dans ce cas, la valeur de la chaîne est convertie en un objet chaîne afin d'accéder à la longueur de la propriété. L'objet string n'est utilisé que pendant une fraction de seconde, après quoi il est sacrifié aux dieux de la collecte des déchets - mais dans l'esprit des émissions de découverte télévisées, nous allons piéger la créature insaisissable et la conserver pour une analyse ultérieure
Pour illustrer ce point, considérons l'exemple suivant dans lequel nous ajoutons une nouvelle propriété au prototype du constructeur String.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
Ainsi, les primitives ont accès à toutes les propriétés (y compris les méthodes) définies par leurs constructeurs d'objets respectifs.
Ainsi, nous avons vu que les types primitifs se convertissent de manière appropriée en leur homologue objet respectif lorsque cela est nécessaire.
Analyse de toString()
méthode
Considérons le code suivant
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
myObj.toString(); // "[object Object]"
myFunc.toString(); // "function(){}"
myString.toString(); // "This is a sample String"
myNumber.toString(); // "4"
myArray.toString(); // "2,3,5"
Comme nous l'avons vu plus haut, ce qui se passe réellement, c'est que lorsque nous appelons toString()
sur un type primitif, il doit être converti en son homologue objet avant de pouvoir invoquer la méthode.
c'est-à-dire myNumber.toString()
est équivalent à Number.prototype.toString.call(myNumber)
et de même pour les autres types primitifs.
Mais que se passerait-il si, au lieu de passer le type primitif dans le fichier toString()
de son homologue de la fonction constructeur Object correspondante, nous forçons le type primitif à être passé en paramètre dans la méthode toString()
du constructeur de la fonction Objet ( Object.prototype.toString.call(x)
) ?
Regardons de plus près Object.prototype.toString()
Conformément à la documentation , Lorsque la méthode toString est appelée, les étapes suivantes sont réalisées :
- Si el
this
valeur est undefined
, retour "[object Undefined]"
.
- Si el
this
valeur est null
, retour "[object Null]"
.
- Si cette valeur n'est pas l'une des valeurs ci-dessus, Let
O
être le résultat d'un appel toObject
en passant le this
en tant qu'argument.
- Soit classe la valeur de la
[[Class]]
propriété interne de O
.
- Renvoie la valeur de la chaîne qui est le résultat de la concaténation des trois chaînes.
"[object "
, class
y "]"
.
Comprenez-le à partir de l'exemple suivant
var myObj = {lhs: 3, rhs: 2};
var myFunc = function(){}
var myString = "This is a sample String";
var myNumber = 4;
var myArray = [2, 3, 5];
var myUndefined = undefined;
var myNull = null;
Object.prototype.toString.call(myObj); // "[object Object]"
Object.prototype.toString.call(myFunc); // "[object Function]"
Object.prototype.toString.call(myString); // "[object String]"
Object.prototype.toString.call(myNumber); // "[object Number]"
Object.prototype.toString.call(myArray); // "[object Array]"
Object.prototype.toString.call(myUndefined); // "[object Undefined]"
Object.prototype.toString.call(myNull); // "[object Null]"
Références : https://es5.github.io/x15.2.html#x15.2.4.2 https://es5.github.io/x9.html#x9.9 https://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/