In JavaScript, it is possible to work with primitives (numbers, strings, and more), as if they were objects.
But, of course, there are notable differences between objects and primitives.
So, primitive is a primitive type value. Seven types of primitives exist, among them are: number, bigint, symbol, string, boolean, null and undefined. An object can store multiple values as properties. You can create an object using {}. For example:
{
name: "Chevrolet",
model: "Camaro",
price: 40000
}
Other kinds of objects also exist in JavaScript. For example, functions are also considered as objects.
One of the most significant advantages of objects is that function can be stored as one of its properties.
For instance:

There are many built-in objects, as well. For example, those that work with errors, dates, HTML elements, and more. They include different methods and properties.
But, note that objects need additional resources for supporting the internal machinery.
A Primitive as an Object
Below is described the paradox of JavaScript:
- One would wish to do many things with primitives such as strings and numbers. Accessing them as methods would be a great thing.
- Primitives have to be both lightweight and fast.
And here is the solution, which may seem a little awkward:
- Primitives remain primitives. One value, as aspired.
- In the language, you have access to the properties and methods of strings, symbols, booleans, and numbers.
- For forcing that work, a unique “object wrapper,” which provides extra functionality is generated, and then is demolished.
Each type of a primitive has its own “object wrapper” called: Number, Boolean, String, Symbol. They provide various sets of methods. For example, there is a string method str.toUpperCase(), returning a capitalized str.
It works in this way:

Now, let’s see what happens in str.toUpperCase():
- str is a primitive. A unique object is created in the moment of accessing its property. That object knows the string value and has helpful methods, such as toUpperCase().
- That method is capable of running and returning an entirely new string ( it is shown by console.log).
- The special object is demolished, and the primitive str is left alone.
We can assume that primitives provide methods, but remain lightweight at the same time.
It is important to note that JavaScript greatly enhances this process. Moreover, the creation of an extra object can be skipped. Anyway, it should still be adhere to the specification behaving as if it generates one.
A number has its methods. Let’s have a look at this example:

Here, toFixed(n) rounds the number to a particular precision.
For instance:

Note that you can use the constructors String/Number/Boolean only internally.
Like some other languages, like Java, give opportunities to create “wrapper objects” for primitives with the following syntax:
new Number(1);
or
new Boolean(false);
Theoretically, it is possible in JavaScript too, but we don’t recommend you to do so. It might bring unwanted outcomes. For example:

In if, objects are always truthy. Here the alert will show the following:

Another useful thing is using the same functions String/Number/Booleanwithout new. With the help of them, value is converted to a string, a number and a boolean.
Here is an example:

Summary
Primitive has a range of helpful methods (except null and undefined). Those methods operate via temporary objects. The engines of JavaScript are properly tuned to enhance that internally. Therefore, it is not expensive to call.