Best Solution: Using typeof & instanceof Operators
function isString(variable) {
return typeof variable === 'string' || variable instanceof String;
}
let greeting = "Hello, world!";
console.log(isString(greeting));
The typeof
operator in JavaScript is a unary operator that returns a string indicating the data type of its operand. The operand can be either a literal or a data structure such as an object.
While the instanceof
operator is a binary operator used to test whether the prototype property of a constructor appears anywhere in the prototype chain of an object. In simpler terms, it checks if an object is an instance of a particular class or constructor.
Why use both operators, you ask? Isn’t one of them enough?
In some cases using only typeof
can be sufficient. But in JavaScript, the handling of strings can be a bit tricky due to the existence of both string primitives and String objects.
Let’s look at the following example where I’m using a primitive string:
let myString = "Hello, World!";
console.log(typeof myString); // Outputs: "string"
In this case, myString
is a string primitive. When we use the typeof
operator with it, it returns “string”.
Let’s try the same with a String object:
let myString = new String("Hello, World!");
console.log(typeof myString); // Outputs: "object"
In this example, myString
is a String object. When we use the typeof
operator with it, it returns “object” because typeof
sees myString
as an instance of the Object class, not specifically a string.
So the best way to check if a variable is a string in JavaScript is to use both the typeof
operator together with the instanceof
operator.
Using the constructor property
The constructor
property in JavaScript returns a reference to the Object constructor function that created the instance of the object. In simpler terms, it tells us what type of object was used to create a particular variable.
Here’s how you can use the constructor
property to check if a variable is a string:
let str = "Hello, world!";
if (str.constructor === String) {
console.log('str is a String');
} else {
console.log('str is not a String');
}
In this example, we’re checking to see if the constructor
of the variable str
is equal to String
. If it is, we know that str
is a String. If it isn’t, str
is not a String.
The above code will output “str is a String
“
However, there is a caveat to this method: it will not work for variables that do not have a constructor
property. This includes null
and undefined
variables. Therefore, before using this method, one must ensure that the variable is defined and is not null.
This method works on both primitive strings and String objects, making it a versatile choice. But as with all methods, it’s important to understand its limitations and use it appropriately.
Object.prototype.toString.call()
My least favorite solution. The .call()
method can be called on the Object.prototype.toString()
function. This is a quite reliable way to get the type of a variable as a string. This method works by using the toString method from Object.prototype and calling it with the variable as the context. The returned string is in the format of "[object Type]"
, where “Type” is the type of the object.
Here’s an example:
let greeting = "Hello, world!";
console.log(Object.prototype.toString.call(greeting) === '[object String]');
In this snippet, Object.prototype.toString.call(greeting)
returns the string "[object String]"
because greeting
is a string. We then compare that result to the string "[object String]"
to check if greeting
is a string. If greeting
is a string, this expression will be true
.
This method is compelling because it works even if the toString
method has been overridden on the object. However, it is a bit more verbose than other methods like typeof
or instanceof
.
Also, note that this method will return "[object Null]"
for null values and "[object Undefined]"
for undefined values. So, if you’re not certain about the possible values of your variable, you may need to handle these cases separately.