Podstawy
Możesz tego nie wiedzieć, ale w JavaScript, ilekroć wchodzimy w interakcję z ciągami, liczbami lub prymitywami logicznymi, wkraczamy w ukryty świat cieni obiektów i przymusu.
string, number, boolean, null, undefined i symbol.
W JavaScript jest 7 prymitywne typy: undefined, null, boolean, string, number, biginti symbol. Wszystko inne jest przedmiotem. Prymitywne typy boolean, stringi numbermogą być owinięte obiektowych ich odpowiedniki. Przedmioty te są instancje Boolean, Stringi Numberkonstruktorzy odpowiednio.
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"
Jeśli prymitywy nie mają właściwości, dlaczego "this is a string".lengthzwraca wartość?
Ponieważ JavaScript z łatwością koeruje między prymitywami a obiektami. W tym przypadku wartość ciągu jest przekształcana w obiekt typu łańcuchowego w celu uzyskania dostępu do długości właściwości. Obiekt string jest używany tylko przez ułamek sekundy, po czym jest składany w ofierze Bogom zbieraczy śmieci - ale zgodnie z duchem programów telewizyjnych, złapiemy nieuchwytne stworzenie i zachowamy je do dalszej analizy…
Aby to jeszcze bardziej zademonstrować, rozważmy następujący przykład, w którym dodajemy nową właściwość do prototypu konstruktora String.
String.prototype.sampleProperty = 5;
var str = "this is a string";
str.sampleProperty; // 5
W ten sposób prymitywy mają dostęp do wszystkich właściwości (w tym metod) zdefiniowanych przez ich konstruktory obiektów.
Widzieliśmy więc, że typy prymitywne będą odpowiednio przekształcać się w odpowiadające im odpowiedniki Object, gdy będzie to wymagane.
Analiza toString()metody
Rozważmy następujący kod
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"
Jak omówiono powyżej, tak naprawdę dzieje się, gdy wywołujemy toString()metodę na typie pierwotnym, zanim będzie mogła wywołać metodę, musi zostać przekształcona w jej odpowiednik obiektowy.
czyli myNumber.toString()jest odpowiednikiem Number.prototype.toString.call(myNumber)i podobnie dla innych typów pierwotnych.
Ale co, jeśli zamiast przekazywania typu pierwotnego do toString()metody odpowiadającego mu odpowiednika funkcji konstruktora Object, wymuszamy przekazanie typu pierwotnego jako parametru do toString()metody konstruktora funkcji Object ( Object.prototype.toString.call(x))?
Bliższe spojrzenie na Object.prototype.toString ()
Zgodnie z dokumentacją , gdy wywoływana jest metoda toString, wykonywane są następujące kroki:
- Jeśli
thiswartość to undefined, return "[object Undefined]".
- Jeśli
thiswartość to null, return "[object Null]".
- Jeśli ta wartość nie jest żadną z powyższych, Niech
Obędzie wynikiem wywołania, toObjectprzekazując thiswartość jako argument.
- Niech class będzie wartością
[[Class]]właściwości wewnętrznej O.
- Zwraca String wartość, która jest wynikiem łącząc trzy struny
"[object ", classi "]".
Zrozum to na podstawie poniższego przykładu
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ódła:
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 / tajne-życie-prymitywów-javascript /