Differencebetween String Primitives and String Objects in JavaScript

What is the difference between string primitives and String objects in JavaScript?

JavaScript has two main type categories, primitives and objects.

var s = 'test';
var ss = new String('test');

The single quote/double quote patterns are identical in terms of functionality. That aside, the behaviour you are trying to name is called auto-boxing. So what actually happens is that a primitive is converted to its wrapper type when a method of the wrapper type is invoked. Put simple:

var s = 'test';

Is a primitive data type. It has no methods, it is nothing more than a pointer to a raw data memory reference, which explains the much faster random access speed.

So what happens when you do s.charAt(i) for instance?

Since s is not an instance of String, JavaScript will auto-box s, which has typeof string to its wrapper type, String, with typeof object or more precisely s.valueOf(s).prototype.toString.call = [object String].

The auto-boxing behaviour casts s back and forth to its wrapper type as needed, but the standard operations are incredibly fast since you are dealing with a simpler data type. However auto-boxing and Object.prototype.valueOf have different effects.

If you want to force the auto-boxing or to cast a primitive to its wrapper type, you can use Object.prototype.valueOf, but the behaviour is different. Based on a wide variety of test scenarios auto-boxing only applies the 'required' methods, without altering the primitive nature of the variable. Which is why you get better speed.

Difference between String() and new String() in Javascript

Using the String() constructor without new gives you the string (primitive) value of the passed parameter. It's like boxing the parameter in a native object if necessary (like a Number or Boolean), and then calling .toString() on it. (Of course if you pass a plain object reference it just calls .toString() on that.)

Calling new String(something) makes a String instance object.

The results look the same via console.log() because it'll just extract the primitive string from the String instance you pass to it.

So: just plain String() returns a string primitive. new String(xyz) returns an object constructed by the String constructor.

It's rarely necessary to explicitly construct a String instance.

Difference between the javascript String Type and String Object?

Strings are a value type in JS, so they can't have any properties attached to them, no prototype, etc. Any attempt to access a property on them is technically performing the JS [[ToObject]] conversion (in essence new String).

Easy way of distinguishing the difference is (in a browser)

a = "foo"
a.b = "bar"
alert("a.b = " + a.b); //Undefined

A = new String("foo");
A.b = "bar";
alert("A.b = " + A.b); // bar

Additionally while

"foo" == new String("foo")

is true, it is only true due to the implicit type conversions of the == operator

"foo" === new String("foo")

will fail.

difference between string object, and primitive string

This statement:

var myString = new String('foo');

...creates a string object initialized with the characters f, o, and o.

This statement:

var myString = new String();

...creates a string object with no characters, but that doesn't matter because this statement:

myString = "foo";

...throws that string object away and replaces that variable's value with a new primitive string with those characters. The net result is exactly the same as:

var myString = "foo";

The reason the output from console.log is different is that the browser providing the console.log is trying to make it clear that one of them is an object and the other is a primitive.

Somewhat confusingly, JavaScript has both string objects and string primitives. (It also has number objects and number primitives.) There is almost never any reason to use new String, which creates a string object; just use the primitive (in your case, a literal) instead. Conversely, there are very good reasons not to use string objects, such as this:

console.log(new String("foo") === new String("foo")); // "false"
console.log(new String("foo") == new String("foo")); // "false"
console.log("foo" === "foo"); // "true"

Because string objects are objects, == and === compare object references, not the sequence of characters. While there may be some edge cases where that's what you want, 99.9% of the time, what you really want is to compare the values. The good news is that:

console.log("foo" == new String("foo")); // "true"

...but that won't be true if you use ===, which doesn't do any type coercion.


You might ask:

So if var myString = "foo" returns a primitive, not an object, how is it that myString.toUpperCase() and such work?

Good question: The answer is that the primitive is automatically promoted to an object so that we can make the function call. (In theory; in practice, implementations are smarter than that.)

whats the difference between string literals, and just a string?

A literal string (or literal <any data type>) means that you just reference the data directly.

For example

"Hello".length // returns 5

The "Hello" is a string literal since we are just referencing it "as-is".
You could do exactly the same thing with a string object:

var strObj = new String("Hello");
strObj.length // returns 5

These two examples are pretty much identical (for the sake of this example). Both create a string variable and measure it's length.
The first uses a string literal and the second uses a string object.


Here is another example using numbers - if you do a direct calculation such as:

5 + 2

you'll be using number literals - again, when you only reference the data directly, it is considered a "literal".

Is there a difference between String(x) and ''

var s1 = 1234 + '';

Creates a string literal. This is a javascript language primitive.

var s2 = String(1234);

The String() function also returns a primitive string literal. s2 will have the same members as s1 because they are both the same type.

However

var s3 = new String("1234");

Will create an object of type String rather than a primitive string literal. This does have different members and is of type object.

Why is the string literal considered a primitive type in JavaScript?

Fundamentally, because the specification says so:

string value

primitive value that is a finite ordered sequence of zero or more 16-bit unsigned integer values

The specification also defines that there are String objects, as distinct from primitive strings. (Similarly there are primitive number, boolean, and symbol types, and Number and Boolean and Symbol objects.)

Primitive strings follow all the rules of other primitives. At a language level, they're treated exactly the way primitive numbers and booleans are. For all intents and purposes, they are primitive values. But as you say, it would be insane for a = b to literally make a copy of the string in b and put that copy in a. Implementations don't have to do that because primitive string values are immutable (just like primitive number values). You can't change any characters in a string, you can only create a new string. If strings were mutable, the implementation would have to make a copy when you did a = b (but if they were mutable the spec would be written differently).

Note that primitive strings and String objects really are different things:

const s = "hey";const o = new String("hey");
// Here, the string `s` refers to is temporarily// converted to a string object so we can perform an// object operation on it (setting a property).s.foo = "bar";// But that temporary object is never stored anywhere,// `s` still just contains the primitive, so getting// the property won't find it:console.log(s.foo); // undefined
// `o` is a String object, which means it can have propertieso.foo = "bar";console.log(o.foo); // "bar"


Related Topics



Leave a reply



Submit