When I started working with JavaScript many years ago, I learned that to convert a value to a string, I could use the following method: value.toString()
.
This method worked well and was enough for me to complete all the tasks at that time. However, as I progressed and started collaborating with other developers, I discovered more ways to convert a value to a string. Here is the full list to be exact:
value.toString()
value + ''
or`${value}`
String(value)
JSON.stringify()
Back then, I was surprised that all four of these ways work slightly differently, and I think experienced developers should be aware of that. That is why we will dive into the differences between all options so you can choose the one that best suits your current needs.
Option #1: value.toString()
value.toString()
is an explicit conversion to a string because you are explicitly calling a method to perform the conversion. This option will work only if the value
is an object that has a toString()
method. Otherwise, it will result in a TypeError. Here are some examples to illustrate the difference:
// The variables below are objects that have toString() method
// Primitive data types such as number and boolean are also objects
const a = 50;
const b = true;
const c = [1, 2, 3];
const d = { name: "Andrew" };
console.log(a.toString()); // => "50"
console.log(b.toString()); // => "true"
console.log(c.toString()); // => "1, 2, 3"
console.log(d.toString()); // => "[object Object]"
// The variables below are not objects and do not have toString()
// method. Calling .toString() on them will result in TypeError
const e = null;
const f = undefined;
console.log(e.toString());
// TypeError: Cannot read properties of null (reading 'toString')
console.log(f.toString());
// TypeError: Cannot read properties of undefined (reading 'toString')
Good news: all objects in JavaScript such as Number, Array, and Function has the toString()
method implemented and it is used when an object needs to be displayed as text (like in HTML), or when an object needs to be used as a string.
The important thing to remember here is that when we call value.toString()
on null
or undefined
, we get a TypeError. This is because those values are not objects and they do not have a toString()
method.
Option #2: String(value)
String(value)
is another explicit way to convert a value to a string using the String constructor. However, it works a bit differently than value.toString()
. When you call String(value)
on null
or undefined
, it will return a string with "null"
or "undefined"
respectively. And this is the most important difference to remember.
const a = 50;
const b = true;
const c = [1, 2, 3];
const d = { name: "Andrew" };
console.log(String(a)); // => "50"
console.log(String(b)); // => "true"
console.log(String(c)); // => "1, 2, 3"
console.log(String(d)); // => "[object Object]"
// Note that we do not get a TypeError
// when calling String() on null or undefined
console.log(String(null)); // => "null"
console.log(String(undefined)); // => "undefined'
One important thing to note: since String is a constructor, it is possible to call it with the new
keyword - new String(value)
. You should rarely use it this way.
When String
is called as a function, it coerces the parameter to a string primitive. However, when String
is called as a constructor (with new
), it creates a String object, which is not a primitive. This produces different results:
const a = new String("Hello from 2023!");
const b = String("Hello from 2023!");
console.log(a); // => String {"Hello, 2023!"}
console.log(b); // => "Hello, 2023!"
console.log(a === 'Hello from 2023!'); // => false
console.log(b === 'Hello from 2023!'); // => true
console.log(a instanceof String); // => true
console.log(b instanceof String); // => false
console.log(typeof a); // => "object"
console.log(typeof b); // => "string"
Option #3: value + "" or `${value}`
When you concatenate a string with any other value, JavaScript will automatically convert the other value to a string. This is an implicit way to convert a value to a string because the +
operator is not specifically designed for string conversion. Instead, it is a general-purpose operator that can be used for addition or string concatenation, depending on the types of the operands.
Good news: This option works pretty much the same as String(value)
, meaning when you try to convert null
or undefined
to string, it will not result in TypeError:
const a = null;
const b = undefined;
console.log(a + ""); // => "null"
console.log(`${a}`); // => "null"
console.log(b + ""); // => "undefined"
console.log(`${b}`); // => "undefined"
However, I am not a big fan of using this method because it involves implicit string conversion and it can be difficult for other developers unfamiliar with JavaScript to understand how the code works at the first glance.
Whenever possible, I prefer to use String(value)
or JSON.stringify(value)
(comes next in the article), which are explicit conversions that do not throw a TypeError when calling on null
or undefined
.
Option #4: JSON.stringify(value)
This method is particularly useful for converting objects and arrays to JSON strings because it can handle nested objects and arrays. Remember what we got when we called value.toString()
or String(value)
on array or objects?
const a = [1, 2, 3];
const b = { name: "Andrew" };
console.log(a.toString()); // => "1,2,3"
console.log(String(a)); // => "1,2,3"
console.log(b.toString()); // => "[object Object]"
console.log(String(b)); // => "[object Object]"
This is not the case with JSON.stringify()
, consider this example:
const a = [1, 2, 3];
const b = { name: "Andrew" };
console.log(JSON.stringify(a)); // => "[1,2,3]"
console.log(JSON.stringify(b)); // => '{"name":"Andrew"}'
As you can see, when we call JSON.stringify()
on arrays, we get a valid JSON array as a string, and when we call JSON.stringify()
on objects, we get a valid JSON object as a string. This also works when we have nested arrays or objects:
const a = [ ['a', 'b'], 5 ];
const b = { name: "Andrew", skills: [ "JavaScript", "TypeScript" ] };
console.log(JSON.stringify(a)); // => '[["a","b"],5]'
console.log(JSON.stringify(b)); // => '{"name":"Andrew","skills":["JavaScript","TypeScript"]}'
Calling JSON.stringify()
on null
or undefined
works the same as with String()
:
console.log(JSON.stringify(null)); // => "null"
console.log(JSON.stringify(undefined)); // => "undefined"
JSON.stringify()
is a more complex method than the previous ones, and in addition to the value to be converted to a string, it also takes two optional parameters: placeholder
and space
. Refer to the MDN Docs if you want to learn more.
Converting Dates to String
When we try to convert JavaScript dates to a string, the first three options work the same, while JSON.stringify()
gives a different result. Consider this example:
const date = new Date(2023, 0, 1, 10, 0, 0);
console.log(String(date));
// => "Sun Jan 01 2023 10:00:00 GMT-0500 (Eastern Standard Time)"
console.log(date.toString());
// => "Sun Jan 01 2023 10:00:00 GMT-0500 (Eastern Standard Time)"
console.log(date + "");
// => "Sun Jan 01 2023 10:00:00 GMT-0500 (Eastern Standard Time)"
console.log(JSON.stringify(date));
// => '"2023-01-01T15:00:00.000Z"'
In this case, JSON.stringify()
returns the date in ISO simplified extended format (ISO 8601). This is because the date object we pass to JSON.stringify()
method implements the toJSON()
method which returns a string (the same as date.toISOString()
).
Always Consider Performance
Now, you may be tempted to use JSON.stringify()
all the time as it offers the most complete conversion. However, you should know that String()
is likely to be faster than JSON.stringify()
because it is a simpler operation that does not involve parsing or formatting the input value as a JSON string.
String()
simply converts the input value to a string using a simple set of rules, as we discussed earlier. This operation is generally fast and efficient, especially for primitive values.
On the other hand, JSON.stringify()
is a more complex operation that involves parsing the input value and generating a JSON string that represents the object in a standardized format. Depending on the size and complexity of the input value, this operation can be relatively slow and resource intensive.
Even though the performance difference may not be significant, I strongly recommend choosing the right method wisely: if you do not need a JSON string in a standardized format, use String(value)
or value.toString()
, otherwise, use JSON. stringify(value)
.
The end. I hope you found this information helpful, stay tuned for more content! :)