String.prototype.toString()

Returns the primitive string value of a String object or string primitive.

Signature
toString()
  • Added in JavaScript ES1

Return value

stringA string representing the specified string value — the primitive held by a String wrapper, or the primitive itself.

Errors

Throws a TypeError if `this` is not a string primitive or a String wrapper object.

String.prototype.toString() overrides Object.prototype.toString() and simply returns the string value it was called on. Its implementation is identical to String.prototype.valueOf(); the pair exists so that a String wrapper object behaves like a primitive in both string and numeric coercion contexts.

When to reach for it

Honestly: rarely, and that is worth knowing. On a primitive it is a no-op. Its real jobs are unwrapping a String object produced by new String() or by Object("x"), and serving as the method the engine calls implicitly during template interpolation and concatenation.

What to use instead

To convert an arbitrary value to a string, call the global String(value). It handles null and undefined, where value.toString() throws a TypeError, and it invokes Symbol.toPrimitive correctly. String() is also the only safe conversion for symbols.

What trips people up

A String wrapper is an object: typeof new String("x") is "object", it is never === to the equivalent primitive, and it is truthy even when it wraps "". This is the bug behind new String("") ? "yes" : "no" printing yes. Do not construct String objects; if one reaches you from an old API, unwrap it immediately.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Unwrap a String object returned by a legacy API back into a primitive
  • Confirm that a value coming from Object(str) behaves as a primitive before comparing it
  • Define a custom toString on your own class so template literals render it usefully

Frequently asked questions

What is the difference between toString and String()?

String(value) works on any value including null, undefined and symbols, while value.toString() throws a TypeError on null or undefined and cannot convert symbols. Prefer the global String() unless you know the value is an object with a toString you want.

What is the difference between String.prototype.toString and valueOf?

For strings they have identical implementations and both return the primitive value. The pair exists so a String wrapper behaves correctly whether the engine asks for a string hint or a number hint during coercion.

Why does typeof return "object" for my string?

Because it was created with new String(...) or Object(...), which produces a wrapper object rather than a primitive. Call .toString() or String() on it to get the primitive back, and avoid new String in new code.

More examples

String() is the safe conversion

String() handles every value, including null and undefined, and reports arrays and plain objects through their own toString. Calling .toString() directly on null throws a TypeError, which is why String(value) is the right default for untrusted input.

Example · javascript
const values = [42, true, null, undefined, [1, 2], { a: 1 }];
console.log(values.map((v) => String(v)));

try {
  null.toString();
} catch (err) {
  console.log(err.name);
}

Implicit calls during coercion

Template interpolation, the + operator and Array.join all coerce through toString, so defining it once makes the object render correctly everywhere. Nothing in the example calls toString explicitly.

Example · javascript
class Money {
  constructor(amount) {
    this.amount = amount;
  }
  toString() {
    return `$${this.amount.toFixed(2)}`;
  }
}

const price = new Money(9.5);
console.log(`Total: ${price}`);
console.log("Total: " + price);
console.log([price, price].join(" and "));

Discussion

  • Be the first to comment on this lesson.