String Primitives and String Objects
JavaScript has primitive string values and `String` wrapper objects, which are different types of values. Primitive strings can still use string methods because JavaScript temporarily boxes them when a property or method is accessed.
A string primitive is a value created with a string literal such as `"hello"`, or by operations that produce a primitive string. Its type is `"string"`, and primitives are immutable.
A `String` object is created explicitly with `new String("hello")`. Its type is `"object"`, and it wraps a primitive string value. Although it represents text, it is not interchangeable with a primitive under strict equality.
When you access a property or method on a string primitive, JavaScript temporarily creates a wrapper-like object so operations such as `"hello".toUpperCase()` can work. This automatic boxing does not turn the original primitive into a persistent object.
In normal application code, string primitives should generally be preferred. Creating wrapper objects can introduce surprising behavior in comparisons, conditionals, collections, and APIs that expect primitive values.
Key points
- String literals produce primitive strings with `typeof` equal to `"string"`.
- `new String("text")` creates a wrapper object with `typeof` equal to `"object"`.
- Primitive strings can call methods through automatic boxing.
- `===` distinguishes a primitive string from a `String` object.
- Prefer primitive strings instead of explicitly constructing `String` objects.
Interview questions
What is the difference between a string primitive and a String object?
A string primitive is a primitive value, such as `"hello"`, while a String object is an object created with `new String("hello")`. Their `typeof` results are `"string"` and `"object"`. Strict equality between them is false because their types differ. In normal JavaScript code, the primitive form is preferred.
Why can a primitive string call methods if primitives are not objects?
JavaScript performs temporary boxing when a property or method is accessed on a primitive string. Conceptually, the primitive is wrapped so the requested method can be found and called. The temporary wrapper does not change the original value into a persistent object. This is why expressions such as `"hello".toUpperCase()` work.
What does strict equality do when comparing a string primitive with a String object?
Strict equality compares values without performing the type coercion associated with loose equality. A string primitive and a String object have different types, so `"hello" === new String("hello")` is false. The object contains a string value, but being wrapped does not make it the same value as the primitive.
Should you use `new String()` in frontend JavaScript?
Usually, no. Primitive strings are simpler and avoid the type differences introduced by wrapper objects. Explicit String objects can cause unexpected results with equality checks and APIs that distinguish objects from primitive values. Use `String(value)` when you need conversion to a primitive string rather than `new String(value)` when possible.
What happens when you access a property on a string primitive?
The language provides temporary object-like behavior for the primitive so that properties and methods can be accessed. For example, a primitive string can expose methods such as `slice()` and `toUpperCase()`. The temporary boxing process allows these operations without changing the primitive into an object. This behavior is one reason JavaScript can make primitives feel object-like in everyday code.