Nozioni di base
Potresti non saperlo ma, in JavaScript, ogni volta che interagiamo con stringhe, numeri o primitive booleane entriamo in un mondo nascosto di ombre di oggetti e coercizione.
stringa, numero, booleano, null, undefined e simbolo.
In JavaScript ci sono 7 tipi primitivi: undefined, null, boolean, string, number, biginte symbol. Tutto il resto è un oggetto. I tipi primitivi boolean, stringe numberpossono essere avvolti dalle loro controparti oggetto. Questi oggetti sono istanze della Boolean, Stringe Numbercostruttori rispettivamente.
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"
Se le primitive non hanno proprietà, perché "this is a string".lengthrestituisce un valore?
Perché JavaScript forzerà prontamente tra primitive e oggetti. In questo caso il valore della stringa viene forzato a un oggetto stringa per accedere alla lunghezza della proprietà. L'oggetto stringa viene utilizzato solo per una frazione di secondo, dopodiché viene sacrificato agli dei della raccolta dei rifiuti - ma nello spirito degli spettacoli televisivi di scoperta, intrappoleremo la creatura sfuggente e la conserveremo per ulteriori analisi ...
Per dimostrarlo ulteriormente, si consideri il seguente esempio in cui si aggiunge una nuova proprietà al prototipo del costruttore di stringhe.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
In questo modo le primitive hanno accesso a tutte le proprietà (inclusi i metodi) definite dai rispettivi costruttori di oggetti.
Quindi abbiamo visto che i tipi primitivi forzeranno in modo appropriato la rispettiva controparte Object quando richiesto.
Analisi del toString()metodo
Considera il codice seguente
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"
Come discusso in precedenza, ciò che sta realmente accadendo è che quando chiamiamo toString()metodo su un tipo primitivo, deve essere forzato nella sua controparte oggetto prima che possa invocare il metodo.
ie myNumber.toString()è equivalente aNumber.prototype.toString.call(myNumber) e in modo simile per altri tipi primitivi.
Ma cosa succede se invece di passare il tipo primitivo nel toString()metodo della sua controparte della funzione costruttore Object corrispondente, forziamo il passaggio del tipo primitivo come parametro sul toString()metodo del costruttore funzione Object ( Object.prototype.toString.call(x))?
Uno sguardo più da vicino a Object.prototype.toString ()
Come da documentazione , quando viene chiamato il metodo toString, vengono eseguiti i seguenti passaggi:
- Se il
thisvalore è undefined, restituisci "[object Undefined]".
- Se il
thisvalore è null, restituisci "[object Null]".
- Se questo valore non è nessuno dei precedenti, Sia
Oil risultato della chiamata toObjectpassando ilthis valore come argomento.
- Sia class il valore della
[[Class]]proprietà interna di O.
- Restituisce il valore stringa che è il risultato di concatenando i tre corde
"[object ", classe "]".
Comprenderlo dal seguente esempio
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]"
Riferimenti:
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-primitive /