6

This question is a spin-off of [] is an instance of Array but "" isn't of String

Given that

"" instanceof String; /* false */
String() instanceof String; /* false */
new String() instanceof String; /* true */

and

typeof "" === "string"; /* true */
typeof String() === "string"; /* true */
typeof new String() === "string"; /* false */

Then, if I have a variable abc and I want to know if it's a string, I can do

if(typeof abc === "string" || abc instanceof String){
    // do something
}

Is there a simpler, shorter and native way of doing this, or must I create my own function?

function isStr(s){
    return typeof s === "string" || s instanceof String;
}
if(isStr(abc)){
    // do something
}
Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • Do you really use `new String()` in your code or it's just a theoretical question? – zerkms Sep 03 '12 at 23:01
  • He might have to deal with other people's code and just wants to be sure he catches all `String` types without reading (or even having access to) all of it. – Vala Sep 03 '12 at 23:04
  • @zerkms It's a theorical question. But it can be a practical question if two programmers are working together and one uses `""` and the other uses `new String()` – Oriol Sep 03 '12 at 23:04
  • @Oriol: yeah, that's why I asked about if you use both (or someone else does), because personally I don't know a reason to use `new String()` and curious if there is any and I just don't know it ;-) – zerkms Sep 03 '12 at 23:05
  • 1
    jQuery just uses `typeof s === "string"` when checking the types of passed in arguments. I suspect this normally works just fine because it's rare for someone to explicitly code a string object from `new String()`. – jfriend00 Sep 03 '12 at 23:15
  • Absolute simplest is to clearly document your API to *require* primitive strings, and then just use `typeof`. There are rare but potential issues with `instanceof`. – gray state is coming Sep 04 '12 at 00:07
  • 1
    possible duplicate of [Check if a variable is a string](http://stackoverflow.com/questions/4059147/check-if-a-variable-is-a-string) – tripleee Sep 04 '12 at 19:20
  • @tripleee This isn't a duplicate of http://stackoverflow.com/questions/4059147/check-if-a-variable-is-a-string. There the asker didn't say that he wanted the code to work with `new String()` too, and it is only said that `typeof myVar == 'string' || myVar instanceof String` can be used. I knew it already, here I asked if there is a native and shorter way of doing that. – Oriol Sep 04 '12 at 22:12
  • possible duplicate of [Check whether variable is number or string in javascript](http://stackoverflow.com/questions/1303646/check-whether-variable-is-number-or-string-in-javascript) – Jonathan Hall Aug 21 '15 at 20:13

3 Answers3

7

I think Object.prototype.toString.call(a) === "[object String]" is the shortest/nativest way of doing this

jbalsas
  • 3,484
  • 22
  • 25
  • 1
    Would ( foo.constructor == String ) not be cleaner? Seems to work for me for both cases but I haven't tested in all engines – Richard Marr Oct 30 '12 at 10:14
1

you are correct:

typeof myVar == 'string' || myVar instanceof String;

is one of the best ways to check if a variable is a string.

Community
  • 1
  • 1
ajax333221
  • 11,436
  • 16
  • 61
  • 95
1

You may be confused because [] is an array initialiser (often called an array literal) that is defined as creating an Array object, whereas '' is a string literal that is defined as creating a string primitive.

A primitive isn't an instance of any kind of object, though it may be coerced to a related object for convenience.

A more important question is why an isString function should return true for both string primitives and string objects? The use of string objects is (extremely?) rare, I would have thought that their use would infer special treatment and that you would want to differentiate between the two and not treat them the same.

It's far more common to ignore the Type of a variable and, where it's Type might vary, unconditionally convert it to the required Type, e.g. if you want a string primitive:

function foo(s) {
  s = String(s); // s is guaranteed to be a string primitive
  ...
}

The exception is where functions are overloaded and have different behaviour depending on whether a particular argument is a Function, Object or whatever. Such overloading is generally not considered a good idea, but many javascript libraries are dependent on it. In those cases, passing a String object rather than a string primitive may have unexpected consequences.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • Precisely this question came to my mind when I was thinking of a function which does different things depending on the type of the argument. – Oriol Sep 04 '12 at 22:18
  • So now you head down the well–trodden path of functions for `isFunction`, `isObject` and so on. :-) Javascript's lose typing means such tests can only work in limited cases, so document the limitations and move on. – RobG Sep 04 '12 at 23:42