6

Until recently, I didn't realise that there are two types of strings (and bools, and numbers) in JavaScript: primitives such as "blah", and objects such as new String("blah").

They differ in very "gotcha"-prone ways, the biggest one of which seems to be the different typeof value ("string" vs "object"), but a number of other differences exist, some documented at MDN.

There's no point in creating String objects because the primitive strings work just as well, and JSHint even treats this as an error. So I'd really like to pretend String instances don't even exist, and only support primitive strings in my code.

This makes me wonder: can I get a surprise String instance by calling some standard API that returns a string? Or is it really safe to assume that unless someone screws up by explicitly writing new String, I will never see one of these?

Roman Starkov
  • 59,298
  • 38
  • 251
  • 324
  • What do you mean by a "standard JavaScript API"? The native JS functions? The DOM apis? Node.js modules? – Bergi Jul 10 '14 at 15:16
  • @Bergi The native functions, the DOM APIs and a vaguely-defined "popular JS libraries". The question is not whether it's theoretically possible to encounter one (the answer to that is obvious), but whether I'd be foolish to assume I won't see one in any reasonably well-coded application. – Roman Starkov Jul 10 '14 at 19:11

2 Answers2

2

This github search shows that some people are using new String.

And this answer has a nice explanation for String obj:

No native JavaScript object, major library or DOM method that returns a string will return a String object rather than a string value. However, if you want to be absolutely sure you have a string value rather than a String object, you can convert it as follows:

var str = new String("foo");
str = "" + str;
Community
  • 1
  • 1
ymutlu
  • 6,585
  • 4
  • 35
  • 47
1

I am not aware of any convention to only use primitive strings. There is also an ever growing amount of API's available, and I'm pretty sure every now and then someone will pull the constructor trick. I would like to give some debugging advice on how to spot this quicky, but I think the typeof check is the only obvious way to quicky note the difference.

You could use a check like this answer, although I think it is not worth the trouble:

function isString(string){
     return typeof myVar == 'string' || myVar instanceof String;
};

isString("foo");             //returns true
isString(new String("bar")); //returns true
isString({});                //returns false;

Conclusion: I'm afraid you just have to pray that you don't encounter these quirky corner cases.

Community
  • 1
  • 1
Justus Romijn
  • 15,699
  • 5
  • 51
  • 63