The basics
You may not know this, but in JavaScript, whenever we interact with string, numeric, or logical primitives, we find ourselves in a hidden world of shadows and casts.
string, number, boolean, zero, undefined value and character.
There are 7 primitive types in JavaScript: undefined , null , boolean , string , number , bigint and symbol . Everything else is an object. The primitive types boolean , string and number can be wrapped by their object counterparts. These objects are instances of the Boolean , String and Number constructors, respectively.
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"
If primitives have no properties, why does "this is a string".length return a value?
Because JavaScript will easily cast between primitives and objects. In this case, the string value is cast to the string object to access the length of the property. A string object is used only for a split second, after which it is sacrificed to the gods of garbage collection - but in the spirit of television discoveries, we will catch an elusive creature and save it for further analysis ...
To demonstrate this further, consider the following example, in which we add a new property to the prototype of the String constructor.
String.prototype.sampleProperty = 5; var str = "this is a string"; str.sampleProperty;
Thus, primitives have access to all properties (including methods) defined by their respective object constructors.
So, we saw that primitive types will accordingly lead to the corresponding object analogue if necessary.
Parsing the toString() Method
Consider the following code
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();
As discussed above, in reality, when we call the toString() method for a primitive type, it must be cast to its object analog before it can call the method.
i.e. myNumber.toString() equivalent to Number.prototype.toString.call(myNumber) and similarly for other primitive types.
But what if, instead of passing the primitive type to the toString() method of the corresponding function-analogue of the constructor of the Object, we force the primitive type to be passed as a parameter to the toString() method of the Object's constructor method ( Object.prototype.toString.call(x) )?
Take a closer look at Object.prototype.toString ()
According to the documentation , When the toString method is called, the following steps are taken:
- If
this is undefined , return "[object Undefined]" . - If
this is null , return "[object Null]" . - If this value is not specified above, let
O be the result of calling toObject with passing the value of this as an argument. - Let class be the value of the
[[Class]] internal property of O - Returns a String value that is the result of combining the three strings
"[object " , class and "]" .
Understand this from the following example.
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);
Links: https://es5.imtqy.com/x15.2.html#x15.2.4.2 https://es5.imtqy.com/x9.html#x9.9 https://javascriptweblog.wordpress.com/ 2010/09/27 / the-secret-life-of-javascript-primitives /