This article is excerpted from the JavaScript Red Book, which is copied here as my own study notes. I hope it can also help you.

1. Basic packaging types

To facilitate manipulation of primitive type values, ECMAScript also provides three special reference types: Boolean, Number, and String. These types are similar to the other reference types covered in this chapter, but also have special behavior corresponding to their respective base types. In fact, every time a primitive type value is read, an object of the corresponding primitive wrapper type is created behind the scenes, allowing us to call methods to manipulate the data. Consider the following example.

var s1 = "some text";
var s2 = s1.substring(2);
Copy the code

The s1 variable in this example contains a string, which is of course a primitive type value. The next line calls s1’s substring() method and stores the returned result in S2. We know that primitive type values are not objects, so logically they should not have methods (although, as we wish, they do).

Second, read mode

In fact, in order for us to achieve this intuitive operation, the background has done a series of automatic processing. When the second line of code accesses S1, it is in read mode, reading the value of the string from memory. When a string is accessed in read mode, the following is done automatically in the background.

  • Create an instance of String.
  • Invokes the specified method on the instance.
  • Destroy the instance.

Think of the above three steps as executing the following ECMAScript code.

var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;
Copy the code

After this processing, the basic string value becomes like an object. Furthermore, these three steps also apply to Boolean and numeric values corresponding to Boolean and Number types, respectively.

The main differences between reference types and basic wrapper types

The main difference between reference types and base wrapper types is the lifetime of the object. Instances of reference types created using the new operator remain in memory until the execution flow leaves the current scope. Objects of the basic wrapper type, created automatically, exist only for the moment a line of code is executed and then destroyed immediately. This means that we cannot add properties and methods for primitive type values at run time. Consider the following example:

var s1 = "some text";
s1.color = "red";
alert(s1.color); //undefined
Copy the code

Here, the second line attempts to add a color attribute to the string s1. However, when the third line of code accesses S1 again, its color attribute is missing. The reason for the problem is that the String created in line 2 has been destroyed by line 3. The third line creates its own String object, which has no color attribute.

Of course, you can explicitly call Boolean, Number, and String to create objects of basic wrapper types. However, you should only do this when absolutely necessary, because it’s easy to confuse whether you’re dealing with values of a primitive type or a reference type. Calling Typeof on instances of the primitive wrapper type returns “object”, and all objects of the primitive wrapper type are converted to a Boolean value of true.

The Object constructor

Like the factory method, the Object constructor returns an instance of the corresponding base wrapper type, depending on the type of the value passed in. Such as:

var obj = new Object("some text");
alert(obj instanceof String); //true
Copy the code

Passing a String to the Object constructor creates an instance of String; Passing a numeric argument returns an instance of Number, and passing a Boolean argument returns an instance of Boolean.

Note that calling the constructor of the base wrapper type with new is not the same as calling the transition function of the same name directly. Such as:

var value = "25";
var number = Number(value); // Transition function
alert(typeof number); //"number"
var obj = new Number(value); // constructor
alert(typeof obj); //"object"
Copy the code

In this example, the value 25 of the primitive type is held in the variable number, while the example of number is held in the variable obj.