27

In JavaScript is there any difference between using String() and new String()?

console.log(String('word')); // word

console.log(new String('word')); // word
cham
  • 8,666
  • 9
  • 48
  • 69
  • 1
    Please be aware that the String object wrapper for string primitive types largely exists for historical reasons, has limited practical use and can be less efficient than using primitive string values. See also https://stackoverflow.com/q/17256182/5217142 – traktor Apr 29 '18 at 02:41

5 Answers5

18

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.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Thanks @Pointy. So String('something') is the same as 'something'? I was just looking at this answer: https://stackoverflow.com/questions/17256182/what-is-the-difference-between-string-literals-and-string-objects-in-javascript/17256340 – cham Apr 29 '18 at 00:41
  • 1
    Yes, in particular calling plain `String()` with a string primitive gives you back that string primitive. It's an idempotent no-op. – Pointy Apr 29 '18 at 00:43
  • 12
    More practically `new String("word") == new String("word")` will be `false` because these are two *different objects*, while `String("word") == String("word")` will be `true` because you are comparing *primitives* – VLAZ Apr 29 '18 at 00:43
13

String() returns a string primitive and new String() returns a Object String. This has some real consequences for your code.

  1. Using String() returns 'true' with other primitives both with == and === operator.
  2. Using String() gives you a primitive so it cannot use the "instanceOf" method to check its type. You can check only value type with "typeof" operator
  3. Using new String() with "instanceOf" method with String or Object prototypes - both assert to true.
  4. Using new String() will return 'true' with string primitives only by calling valueOf() method. String() has also this method and returns true when compared to string of the same value.
  5. Using new String() allows you to add some other properties and methods to the Object to allow more complex behaviour.

From my coding experience you should avoid using new String() if you have no need for adding special methods to your String Object.

    var x = String('word');
    console.log(typeof x); // "string"
    var y = new String('word');
    console.log(typeof y); // "object"

    // compare two objects !!!
    console.log(new String('') === new String('')) // false!!!

    // compare with string primitive
    console.log('' == String('')) // true
    console.log('' === String('')) // true

    //compare with string Object
    console.log('' == new String('')) // true

    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    console.log('' === new String('')) // false !!!!
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    // instance of behavior
    console.log(x instanceof String); // false
    console.log(x instanceof Object); // false

    // please note that only new String() is a instanceOf Object and String
    console.log(y instanceof String); // true
    console.log(y instanceof Object); // true

    //valueOf behavior
    console.log('word' == x.valueOf()); // true
    console.log('word' === x.valueOf()); // true

    console.log('word' == y.valueOf()); // true
    console.log('word' === y.valueOf()); // true

    //create smart string
    var superString = new String('Voice')
    superString.powerful = 'POWERFUL'
    String.prototype.shout = function () {
        return `${this.powerful} ${this.toUpperCase()}`
    };

    console.log(superString.shout()) //"POWERFUL VOICE"
twboc
  • 1,452
  • 13
  • 17
6

Strings returned from String calls in a non-constructor context (i.e., without using the new keyword) are primitive strings.

Strings created with new String() (constructor mode) is an object and can store property in them.

Demonstrating the difference:

var strPrimitive = String('word');
strPrimitive.prop = "bar";
console.log(strPrimitive.prop); // undefined

var strObject = new String('word');
strObject.prop = "bar";
console.log(strObject.prop); // bar
Shaya Ulman
  • 1,299
  • 1
  • 12
  • 24
Mamun
  • 66,969
  • 9
  • 47
  • 59
  • 1
    Thank you @Mamun. So is adding properties the main reason you would choose to use new String()? – cham Apr 29 '18 at 00:58
  • 1
    @cham, since there is no other differences between them other than the type, I would use `new String()` when I need them as object.....thanks. – Mamun Apr 29 '18 at 01:02
3

Here is an example in addition to the good answers already provided:

var x = String('word');
console.log(typeof x); // "string"

var y = new String('word');
console.log(typeof y); // "object"

The exact answer to your question is here in the documentation.

String literals (denoted by double or single quotes) and strings returned from String calls in a non-constructor context (i.e., without using the new keyword) are primitive strings.

Sébastien
  • 11,860
  • 11
  • 58
  • 78
1

Generally it's not recommended to use constructor functions (i.e. using new keyword) because it can lead to unpredictable results.

For example:

if (new Number(0)) { // 
    console.log('It will be executed because object always treated as TRUE in logical contexts. If you want to treat 0 as falsy value then use Number(0)')
}

Also, as mentioned above, there is another potential problem:

typeof 0; // number
typeof Number(0) // number
typeof new Number(0) // object

WelcomeTo
  • 19,843
  • 53
  • 170
  • 286