9

my problem is described below with example number-1:

 var myString = new String('foo');

if i use console.log(myString); the output is String { 0="f", 1="o", 2="o"}

and number-2:

var myString = new String();
myString = "foo";

here console.log(mystring); prints just foo

here what is the difference between number-1 and number-2 ? why the ouput is different ?

3
  • 1
    new String() part in the second is redundant Commented Jun 27, 2013 at 22:03
  • 1
    Notice that in the number-2 you are overriding the first assignment. Commented Jun 27, 2013 at 22:03
  • 2
    One is an object, the other is a primitive. Commented Jun 27, 2013 at 22:04

3 Answers 3

14

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.)

Sign up to request clarification or add additional context in comments.

5 Comments

"Somewhat confusingly" --- if you didn't have string objects - you wouldn't have 'str'.length and other wrapper-related things working
@zerkms: While true, that's just a language mechanism. At the end of the day, 99.9% of the time, you can (and should) use primitives that get auto-promoted as necessary.
Good point, @zerkms, but maybe he's suggesting that they should all be objects automagically.
@T.J.Crowder: thank you sir. i am beginner in JS. i hv finished almost the basic things of JavaScript. but i dont understand how should i proceed. i m confused what and how can i improve my skill and feeling scattered. do u plz tell me a proper and structured way so that i can make myself better in javaScript. it will be helpful if u give suggestion. thank u again
@skipperkhan: No worries. I'm not sure I can, but it's well worth reading some good books on JavaScript (David Flanagan's JavaScript: The Definitive Guide for instance), and reading some online material (perhaps including -- very much in the minor category -- my blog). One of the big things about JavaScript that may not be clear to you (based on the question) is that it's loosely typed. A variable is just a variable, it can contain anything, and it can contain different things (objects, numbers, ...) at different times.
2

The best way to understand is by running these 2 statements

console.log(typeof 'foo'); // -> "string"

console.log(typeof new String('foo')); // -> "object"

Also the second statement you are reassigning myString to a "string" instead of String object

Comments

2
console.log(typeof s_prim); // Logs "string"
console.log(typeof s_obj);  // Logs "object"

The difference is subtle, especially because methods called on string primitives are wrapped by string object methods, so functionally they are close to the same.

As pointed out in the MDN reference, this may matter on eval() calls. Eval will return the object "2 + 2" if called on the string object, and 4 if called on the primitive.

1 Comment

+1 for the actual reference. It pretty much explains everythin there is to know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.