JavaScript identity operator on strings - javascript

I'm trying to write a prototype for determining if a string is empty. It's really just playing with JS and prototype, nothing important. Here's my code:
String.prototype.IsEmpty = function() {
return (this === "");
}
Notice I used the === identity comparison instead of == equality. When I run the function with the above definition:
"".IsEmpty(); // false
If I chagne the definition to use == as:
String.prototype.IsEmpty = function() {
return (this == "");
}
The new def'n will do:
"".IsEmpty(); // true
I don't understand why === doesn't work since "" is identical to ""

It's because "" is a string primitive, but when you call .IsEmpty() it's implicitly converted to a String object.
You'd need to call .toString() on it:
String.prototype.IsEmpty = function() {
return (this.toString() === "");
}
Interestingly this is browser-specific - typeof this is string in Chrome.
As #pst points out, if you were to convert the other way and compare this === new String(""); it still wouldn't work, as they're different instances.

=== is identity (same object; x is x**). == is equality (same value; x looks like y).
Lets play some (Rhino / JS 1.8):
{} === {} // false
new String("") === new String("") // false
typeof new String("") // object
"" === "" // true
typeof "" // string
f = function () { return "f" };
"foo" === f() + "oo" // true
String.prototype.foo = function () { return this; };
typeof "hello".foo() // object -- uh, oh! it was lifted
So, what just happened?
The difference between a String object and string. Of course, the equality compare (or .length) should be used.
The proof in the pudding, section 11.9.6 discusses the === operator algorithm

Related

A way to check for undefined null and 0 [duplicate]

Is there a universal JavaScript function that checks that a variable has a value and ensures that it's not undefined or null? I've got this code, but I'm not sure if it covers all cases:
function isEmpty(val){
return (val === undefined || val == null || val.length <= 0) ? true : false;
}
You can just check if the variable has a truthy value or not. That means
if (value) {
// do something..
}
will evaluate to true if value is not:
null
undefined
NaN
empty string ("")
0
false
The above list represents all possible falsy values in ECMA-/Javascript. Find it in the specification at the ToBoolean section.
Furthermore, if you do not know whether a variable exists (that means, if it was declared) you should check with the typeof operator. For instance
if (typeof foo !== 'undefined') {
// foo could get resolved and it's defined
}
If you can be sure that a variable is declared at least, you should directly check if it has a truthy value like shown above.
The verbose method to check if value is undefined or null is:
return value === undefined || value === null;
You can also use the == operator but this expects one to know all the rules:
return value == null; // also returns true if value is undefined
function isEmpty(value){
return (value == null || value.length === 0);
}
This will return true for
undefined // Because undefined == null
null
[]
""
and zero argument functions since a function's length is the number of declared parameters it takes.
To disallow the latter category, you might want to just check for blank strings
function isEmpty(value){
return (value == null || value === '');
}
Null or whitespace
function isEmpty(value){
return (value == null || value.trim().length === 0);
}
This is the safest check and I haven't seen it posted here exactly like that:
if (typeof value !== 'undefined' && value) {
//deal with value'
};
It will cover cases where value was never defined, and also any of these:
null
undefined (value of undefined is not the same as a parameter that was never defined)
0
"" (empty string)
false
NaN
Edited: Changed to strict equality (!==) because it's the norm by now ;)
You may find the following function useful:
function typeOf(obj) {
return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
Or in ES7 (comment if further improvements)
function typeOf(obj) {
const { toString } = Object.prototype;
const stringified = obj::toString();
const type = stringified.split(' ')[1].slice(0, -1);
return type.toLowerCase();
}
Results:
typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map
"Note that the bind operator (::) is not part of ES2016 (ES7) nor any later edition of the ECMAScript standard at all. It's currently a stage 0 (strawman) proposal for being introduced to the language." – Simon Kjellberg. the author wishes to add his support for this beautiful proposal to receive royal ascension.
A solution I like a lot:
Let's define that a blank variable is null, or undefined, or if it has length, it is zero, or if it is an object, it has no keys:
function isEmpty (value) {
return (
// null or undefined
(value == null) ||
// has length and it's zero
(value.hasOwnProperty('length') && value.length === 0) ||
// is an Object and has no keys
(value.constructor === Object && Object.keys(value).length === 0)
)
}
Returns:
true: undefined, null, "", [], {}
false: true, false, 1, 0, -1, "foo", [1, 2, 3], { foo: 1 }
This condition check
if (!!foo) {
//foo is defined
}
is all you need.
Take a look at the new ECMAScript Nullish coalescing operator
You can think of this feature - the ?? operator - as a way to “fall back” to a default value when dealing with null or undefined.
let x = foo ?? bar();
Again, the above code is equivalent to the following.
let x = (foo !== null && foo !== undefined) ? foo : bar();
The first answer with best rating is wrong. If value is undefined it will throw an exception in modern browsers. You have to use:
if (typeof(value) !== "undefined" && value)
or
if (typeof value !== "undefined" && value)
! check for empty strings (""), null, undefined, false and the number 0 and NaN. Say, if a string is empty var name = "" then console.log(!name) returns true.
function isEmpty(val){
return !val;
}
this function will return true if val is empty, null, undefined, false, the number 0 or NaN.
OR
According to your problem domain you can just use like !val or !!val.
You are a bit overdoing it. To check if a variable is not given a value, you would only need to check against undefined and null.
function isEmpty(value){
return (typeof value === "undefined" || value === null);
}
This is assuming 0, "", and objects(even empty object and array) are valid "values".
Vacuousness
I don't recommend trying to define or use a function which computes whether any value in the whole world is empty. What does it really mean to be "empty"? If I have let human = { name: 'bob', stomach: 'empty' }, should isEmpty(human) return true? If I have let reg = new RegExp('');, should isEmpty(reg) return true? What about isEmpty([ null, null, null, null ]) - this list only contains emptiness, so is the list itself empty? I want to put forward here some notes on "vacuousness" (an intentionally obscure word, to avoid pre-existing associations) in javascript - and I want to argue that "vacuousness" in javascript values should never be dealt with generically.
Truthiness/Falsiness
For deciding how to determine the "vacuousness" of values, we need to accomodate javascript's inbuilt, inherent sense of whether values are "truthy" or "falsy". Naturally, null and undefined are both "falsy". Less naturally, the number 0 (and no other number except NaN) is also "falsy". Least naturally: '' is falsy, but [] and {} (and new Set(), and new Map()) are truthy - although they all seem equally vacuous!
Null vs Undefined
There is also some discussion concerning null vs undefined - do we really need both in order to express vacuousness in our programs? I personally avoid ever having undefined appear in my code. I always use null to signify "vacuousness". Again, though, we need to accomodate javascript's inherent sense of how null and undefined differ:
Trying to access a non-existent property gives undefined
Omitting a parameter when calling a function results in that parameter receiving undefined:
let f = a => a;
console.log(f('hi'));
console.log(f());
Parameters with default values receive the default only when given undefined, not null:
let f = (v='hello') => v;
console.log(f(null));
console.log(f(undefined));
To me, null is an explicit signifier of vacuousness; "something that could have been filled in was intentionally left blank".
Really undefined is a necessary complication that allows some js features to exist, but in my opinion it should always be left behind the scenes; not interacted with directly. We can think of undefined as, for example, javascript's mechanic for implementing default function arguments. If you refrain from supplying an argument to a function it will receive a value of undefined instead. And a default value will be applied to a function argument if that argument was initially set to undefined. In this case undefined is the linchpin of default function arguments, but it stays in the background: we can achieve default argument functionality without ever referring to undefined:
This is a bad implementation of default arguments as it interacts directly with undefined:
let fnWithDefaults = arg => {
if (arg === undefined) arg = 'default';
...
};
This is a good implementation:
let fnWithDefaults = (arg='default') => { ... };
This is a bad way to accept the default argument:
fnWithDefaults(undefined);
Simply do this instead:
fnWithDefaults();
By the way: do you have a function with multiple arguments, and you want to provide some arguments while accepting defaults for others?
E.g.:
let fnWithDefaults = (a=1, b=2, c=3, d=4) => console.log(a, b, c, d);
If you want to provide values for a and d and accepts defaults for the others what to do? This seems wrong:
fnWithDefaults(10, undefined, undefined, 40);
The answer is: refactor fnWithDefaults to accept a single object:
let fnWithDefaults = ({ a=1, b=2, c=3, d=4 }={}) => console.log(a, b, c, d);
fnWithDefaults({ a: 10, d: 40 }); // Now this looks really nice! (And never talks about "undefined")
Non-generic Vacuousness
I believe that vacuousness should never be dealt with in a generic fashion. We should instead always have the rigour to get more information about our data before determining if it is vacuous - I mainly do this by checking what type of data I'm dealing with:
let isType = (value, Cls) => {
// Intentional use of loose comparison operator detects `null`
// and `undefined`, and nothing else!
return value != null && Object.getPrototypeOf(value).constructor === Cls;
};
Note that this function ignores inheritance - it expects value to be a direct instance of Cls, and not an instance of a subclass of Cls. I avoid instanceof for two main reasons:
([] instanceof Object) === true ("An Array is an Object")
('' instanceof String) === false ("A String is not a String")
Note that Object.getPrototypeOf is used to avoid an (obscure) edge-case such as let v = { constructor: String }; The isType function still returns correctly for isType(v, String) (false), and isType(v, Object) (true).
Overall, I recommend using this isType function along with these tips:
Minimize the amount of code processing values of unknown type. E.g., for let v = JSON.parse(someRawValue);, our v variable is now of unknown type. As early as possible, we should limit our possibilities. The best way to do this can be by requiring a particular type: e.g. if (!isType(v, Array)) throw new Error('Expected Array'); - this is a really quick and expressive way to remove the generic nature of v, and ensure it's always an Array. Sometimes, though, we need to allow v to be of multiple types. In those cases, we should create blocks of code where v is no longer generic, as early as possible:
if (isType(v, String)) {
/* v isn't generic in this block - It's a String! */
} else if (isType(v, Number)) {
/* v isn't generic in this block - It's a Number! */
} else if (isType(v, Array)) {
/* v isn't generic in this block - it's an Array! */
} else {
throw new Error('Expected String, Number, or Array');
}
Always use "whitelists" for validation. If you require a value to be, e.g., a String, Number, or Array, check for those 3 "white" possibilities, and throw an Error if none of the 3 are satisfied. We should be able to see that checking for "black" possibilities isn't very useful: Say we write if (v === null) throw new Error('Null value rejected'); - this is great for ensuring that null values don't make it through, but if a value does make it through, we still know hardly anything about it. A value v which passes this null-check is still VERY generic - it's anything but null! Blacklists hardly dispell generic-ness.
Unless a value is null, never consider "a vacuous value". Instead, consider "an X which is vacuous". Essentially, never consider doing anything like if (isEmpty(val)) { /* ... */ } - no matter how that isEmpty function is implemented (I don't want to know...), it isn't meaningful! And it's way too generic! Vacuousness should only be calculated with knowledge of val's type. Vacuousness-checks should look like this:
"A string, with no chars":
if (isType(val, String) && val.length === 0) ...
"An Object, with 0 props": if (isType(val, Object) && Object.entries(val).length === 0) ...
"A number, equal or less than zero": if (isType(val, Number) && val <= 0) ...
"An Array, with no items": if (isType(val, Array) && val.length === 0) ...
The only exception is when null is used to signify certain functionality. In this case it's meaningful to say: "A vacuous value": if (val === null) ...
The probably shortest answer is
val==null || val==''
if you change rigth side to val==='' then empty array will give false. Proof
function isEmpty(val){
return val==null || val==''
}
// ------------
// TEST
// ------------
var log = (name,val) => console.log(`${name} -> ${isEmpty(val)}`);
log('null', null);
log('undefined', undefined);
log('NaN', NaN);
log('""', "");
log('{}', {});
log('[]', []);
log('[1]', [1]);
log('[0]', [0]);
log('[[]]', [[]]);
log('true', true);
log('false', false);
log('"true"', "true");
log('"false"', "false");
log('Infinity', Infinity);
log('-Infinity', -Infinity);
log('1', 1);
log('0', 0);
log('-1', -1);
log('"1"', "1");
log('"0"', "0");
log('"-1"', "-1");
// "void 0" case
console.log('---\n"true" is:', true);
console.log('"void 0" is:', void 0);
log(void 0,void 0); // "void 0" is "undefined" - so we should get here TRUE
More details about == (source here)
BONUS: Reason why === is more clear than ==
To write clear and easy
understandable code, use explicite list of accepted values
val===undefined || val===null || val===''|| (Array.isArray(val) && val.length===0)
function isEmpty(val){
return val===undefined || val===null || val==='' || (Array.isArray(val) && val.length===0)
}
// ------------
// TEST
// ------------
var log = (name,val) => console.log(`${name} -> ${isEmpty(val)}`);
log('null', null);
log('undefined', undefined);
log('NaN', NaN);
log('""', "");
log('{}', {});
log('[]', []);
log('[1]', [1]);
log('[0]', [0]);
log('[[]]', [[]]);
log('true', true);
log('false', false);
log('"true"', "true");
log('"false"', "false");
log('Infinity', Infinity);
log('-Infinity', -Infinity);
log('1', 1);
log('0', 0);
log('-1', -1);
log('"1"', "1");
log('"0"', "0");
log('"-1"', "-1");
// "void 0" case
console.log('---\n"true" is:', true);
console.log('"void 0" is:', void 0);
log(void 0,void 0); // "void 0" is "undefined" - so we should get here TRUE
Here's mine - returns true if value is null, undefined, etc or blank (ie contains only blank spaces):
function stringIsEmpty(value) {
return value ? value.trim().length == 0 : true;
}
If you prefer plain javascript try this:
/**
* Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
* length of `0` and objects with no own enumerable properties are considered
* "empty".
*
* #static
* #memberOf _
* #category Objects
* #param {Array|Object|string} value The value to inspect.
* #returns {boolean} Returns `true` if the `value` is empty, else `false`.
* #example
*
* _.isEmpty([1, 2, 3]);
* // => false
*
* _.isEmpty([]);
* // => true
*
* _.isEmpty({});
* // => true
*
* _.isEmpty('');
* // => true
*/
function isEmpty(value) {
if (!value) {
return true;
}
if (isArray(value) || isString(value)) {
return !value.length;
}
for (var key in value) {
if (hasOwnProperty.call(value, key)) {
return false;
}
}
return true;
}
Otherwise, if you are already using underscore or lodash, try:
_.isEmpty(value)
return val || 'Handle empty variable'
is a really nice and clean way to handle it in a lot of places, can also be used to assign variables
const res = val || 'default value'
If the variable hasn't been declared, you wont be able to test for undefined using a function because you will get an error.
if (foo) {}
function (bar) {}(foo)
Both will generate an error if foo has not been declared.
If you want to test if a variable has been declared you can use
typeof foo != "undefined"
if you want to test if foo has been declared and it has a value you can use
if (typeof foo != "undefined" && foo) {
//code here
}
You could use the nullish coalescing operator ?? to check for null and undefined values. See the MDN Docs
null ?? 'default string'; // returns "default string"
0 ?? 42; // returns 0
(null || undefined) ?? "foo"; // returns "foo"
To check Default Value
function typeOfVar (obj) {
return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
function isVariableHaveDefaltVal(variable) {
if ( typeof(variable) === 'string' ) { // number, boolean, string, object
console.log(' Any data Between single/double Quotes is treated as String ');
return (variable.trim().length === 0) ? true : false;
}else if ( typeof(variable) === 'boolean' ) {
console.log('boolean value with default value \'false\'');
return (variable === false) ? true : false;
}else if ( typeof(variable) === 'undefined' ) {
console.log('EX: var a; variable is created, but has the default value of undefined.');
return true;
}else if ( typeof(variable) === 'number' ) {
console.log('number : '+variable);
return (variable === 0 ) ? true : false;
}else if ( typeof(variable) === 'object' ) {
// -----Object-----
if (typeOfVar(variable) === 'array' && variable.length === 0) {
console.log('\t Object Array with length = ' + [].length); // Object.keys(variable)
return true;
}else if (typeOfVar(variable) === 'string' && variable.length === 0 ) {
console.log('\t Object String with length = ' + variable.length);
return true;
}else if (typeOfVar(variable) === 'boolean' ) {
console.log('\t Object Boolean = ' + variable);
return (variable === false) ? true : false;
}else if (typeOfVar(variable) === 'number' ) {
console.log('\t Object Number = ' + variable);
return (variable === 0 ) ? true : false;
}else if (typeOfVar(variable) === 'regexp' && variable.source.trim().length === 0 ) {
console.log('\t Object Regular Expression : ');
return true;
}else if (variable === null) {
console.log('\t Object null value');
return true;
}
}
return false;
}
var str = "A Basket For Every Occasion";
str = str.replace(/\s/g, "-");
//The "g" flag in the regex will cause all spaces to get replaced.
check Result:
isVariableHaveDefaltVal(' '); // string
isVariableHaveDefaltVal(false); // boolean
var a;
isVariableHaveDefaltVal(a);
isVariableHaveDefaltVal(0); // number
isVariableHaveDefaltVal(parseInt('')); // NAN isNAN(' '); - true
isVariableHaveDefaltVal(null);
isVariableHaveDefaltVal([]);
isVariableHaveDefaltVal(/ /);
isVariableHaveDefaltVal(new Object(''));
isVariableHaveDefaltVal(new Object(false));
isVariableHaveDefaltVal(new Object(0));
typeOfVar( function() {} );
I used #Vix function() to check the object of which type.
using instansof «
var prototypes_or_Literals = function (obj) {
switch (typeof(obj)) {
// object prototypes
case 'object':
if (obj instanceof Array)
return '[object Array]';
else if (obj instanceof Date)
return '[object Date]';
else if (obj instanceof RegExp)
return '[object regexp]';
else if (obj instanceof String)
return '[object String]';
else if (obj instanceof Number)
return '[object Number]';
else
return 'object';
// object literals
default:
return typeof(obj);
}
};
output test «
prototypes_or_Literals( '' ) // "string"
prototypes_or_Literals( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]"
function isEmpty(obj) {
if (typeof obj == 'number') return false;
else if (typeof obj == 'string') return obj.length == 0;
else if (Array.isArray(obj)) return obj.length == 0;
else if (typeof obj == 'object') return obj == null || Object.keys(obj).length == 0;
else if (typeof obj == 'boolean') return false;
else return !obj;
}
In ES6 with trim to handle whitespace strings:
const isEmpty = value => {
if (typeof value === 'number') return false
else if (typeof value === 'string') return value.trim().length === 0
else if (Array.isArray(value)) return value.length === 0
else if (typeof value === 'object') return value == null || Object.keys(value).length === 0
else if (typeof value === 'boolean') return false
else return !value
}
It may be usefull.
All values in array represent what you want to be (null, undefined or another things) and you search what you want in it.
var variablesWhatILookFor = [null, undefined, ''];
variablesWhatILookFor.indexOf(document.DocumentNumberLabel) > -1
If you are using TypeScript and don't want to account for "values those are false" then this is the solution for you:
First: import { isNullOrUndefined } from 'util';
Then: isNullOrUndefined(this.yourVariableName)
Please Note: As mentioned below this is now deprecated, use value === undefined || value === null instead. ref.
Try With Different Logic. You can use bellow code for check all four(4) condition for validation like not null, not blank, not undefined and not zero only use this code (!(!(variable))) in javascript and jquery.
function myFunction() {
var data; //The Values can be like as null, blank, undefined, zero you can test
if(!(!(data)))
{
alert("data "+data);
}
else
{
alert("data is "+data);
}
}
The optional chaining operator provides a way to simplify accessing values through connected objects when it's possible that a reference or function may be undefined or null.
let customer = {
name: "Carl",
details: {
age: 82,
location: "Paradise Falls" // detailed address is unknown
}
};
let customerCity = customer.details?.address?.city;
The nullish coalescing operator may be used after optional chaining in order to build a default value when none was found:
let customer = {
name: "Carl",
details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city
function isEmpty(val){
return !val;
}
but this solution is over-engineered, if you dont'want to modify the function later for busines-model needings, then is cleaner to use it directly in code:
if(!val)...
var myNewValue = myObject && myObject.child && myObject.child.myValue;
This will never throw an error. If myObject, child, or myValue is null then myNewValue will be null. No errors will be thrown
For everyone coming here for having similar question, the following works great and I have it in my library the last years:
(function(g3, $, window, document, undefined){
g3.utils = g3.utils || {};
/********************************Function type()********************************
* Returns a lowercase string representation of an object's constructor.
* #module {g3.utils}
* #function {g3.utils.type}
* #public
* #param {Type} 'obj' is any type native, host or custom.
* #return {String} Returns a lowercase string representing the object's
* constructor which is different from word 'object' if they are not custom.
* #reference http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
* http://stackoverflow.com/questions/3215046/differentiating-between-arrays-and-hashes-in-javascript
* http://javascript.info/tutorial/type-detection
*******************************************************************************/
g3.utils.type = function (obj){
if(obj === null)
return 'null';
else if(typeof obj === 'undefined')
return 'undefined';
return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
};
}(window.g3 = window.g3 || {}, jQuery, window, document));
If you want to avoid getting true if the value is any of the following, according to jAndy's answer:
null
undefined
NaN
empty string ("")
0
false
One possible solution that might avoid getting truthy values is the following:
function isUsable(valueToCheck) {
if (valueToCheck === 0 || // Avoid returning false if the value is 0.
valueToCheck === '' || // Avoid returning false if the value is an empty string.
valueToCheck === false || // Avoid returning false if the value is false.
valueToCheck) // Returns true if it isn't null, undefined, or NaN.
{
return true;
} else {
return false;
}
}
It would be used as follows:
if (isUsable(x)) {
// It is usable!
}
// Make sure to avoid placing the logical NOT operator before the parameter (isUsable(!x)) and instead, use it before the function, to check the returned value.
if (!isUsable(x)) {
// It is NOT usable!
}
In addition to those scenarios, you may want to return false if the object or array is empty:
Object: {} (Using ECMA 7+)
Array: [] (Using ECMA 5+)
You would go about it this way:
function isEmptyObject(valueToCheck) {
if(typeof valueToCheck === 'object' && !Object.keys(valueToCheck).length){
// Object is empty!
return true;
} else {
// Object is not empty!
return false;
}
}
function isEmptyArray(valueToCheck) {
if(Array.isArray(valueToCheck) && !valueToCheck.length) {
// Array is empty!
return true;
} else {
// Array is not empty!
return false;
}
}
If you wish to check for all whitespace strings (" "), you may do the following:
function isAllWhitespace(){
if (valueToCheck.match(/^ *$/) !== null) {
// Is all whitespaces!
return true;
} else {
// Is not all whitespaces!
return false;
}
}
Note: hasOwnProperty returns true for empty strings, 0, false, NaN, null, and undefined, if the variable was declared as any of them, so it might not be the best to use. The function may be modified to use it to show that it was declared, but is not usable.
Code on GitHub
const isEmpty = value => (
(!value && value !== 0 && value !== false)
|| (Array.isArray(value) && value.length === 0)
|| (isObject(value) && Object.keys(value).length === 0)
|| (typeof value.size === 'number' && value.size === 0)
// `WeekMap.length` is supposed to exist!?
|| (typeof value.length === 'number'
&& typeof value !== 'function' && value.length === 0)
);
// Source: https://levelup.gitconnected.com/javascript-check-if-a-variable-is-an-object-and-nothing-else-not-an-array-a-set-etc-a3987ea08fd7
const isObject = value =>
Object.prototype.toString.call(value) === '[object Object]';
Poor man's tests 😁
const test = () => {
const run = (label, values, expected) => {
const length = values.length;
console.group(`${label} (${length} tests)`);
values.map((v, i) => {
console.assert(isEmpty(v) === expected, `${i}: ${v}`);
});
console.groupEnd();
};
const empty = [
null, undefined, NaN, '', {}, [],
new Set(), new Set([]), new Map(), new Map([]),
];
const notEmpty = [
' ', 'a', 0, 1, -1, false, true, {a: 1}, [0],
new Set([0]), new Map([['a', 1]]),
new WeakMap().set({}, 1),
new Date(), /a/, new RegExp(), () => {},
];
const shouldBeEmpty = [
{undefined: undefined}, new Map([[]]),
];
run('EMPTY', empty, true);
run('NOT EMPTY', notEmpty, false);
run('SHOULD BE EMPTY', shouldBeEmpty, true);
};
Test results:
EMPTY (10 tests)
NOT EMPTY (16 tests)
SHOULD BE EMPTY (2 tests)
Assertion failed: 0: [object Object]
Assertion failed: 1: [object Map]
function notEmpty(value){
return (typeof value !== 'undefined' && value.trim().length);
}
it will also check white spaces (' ') along with following:
null ,undefined ,NaN ,empty ,string ("") ,0 ,false

Find out what kind of object a thing is in Javascript/Coffeescript when foo.prototype is undefined? [duplicate]

Is there a JavaScript equivalent of Java's class.getName()?
Is there a JavaScript equivalent of Java's class.getName()?
No.
ES2015 Update: the name of class Foo {} is Foo.name. The name of thing's class, regardless of thing's type, is thing.constructor.name. Builtin constructors in an ES2015 environment have the correct name property; for instance (2).constructor.name is "Number".
But here are various hacks that all fall down in one way or another:
Here is a hack that will do what you need - be aware that it modifies the Object's prototype, something people frown upon (usually for good reason)
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
Now, all of your objects will have the function, getName(), that will return the name of the constructor as a string. I have tested this in FF3 and IE7, I can't speak for other implementations.
If you don't want to do that, here is a discussion on the various ways of determining types in JavaScript...
I recently updated this to be a bit more exhaustive, though it is hardly that. Corrections welcome...
Using the constructor property...
Every object has a value for its constructor property, but depending on how that object was constructed as well as what you want to do with that value, it may or may not be useful.
Generally speaking, you can use the constructor property to test the type of the object like so:
var myArray = [1,2,3];
(myArray.constructor == Array); // true
So, that works well enough for most needs. That said...
Caveats
Will not work AT ALL in many cases
This pattern, though broken, is quite common:
function Thingy() {
}
Thingy.prototype = {
method1: function() {
},
method2: function() {
}
};
Objects constructed via new Thingy will have a constructor property that points to Object, not Thingy. So we fall right at the outset; you simply cannot trust constructor in a codebase that you don't control.
Multiple Inheritance
An example where it isn't as obvious is using multiple inheritance:
function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a
Things now don't work as you might expect them to:
var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true
So, you might get unexpected results if the object your testing has a different object set as its prototype. There are ways around this outside the scope of this discussion.
There are other uses for the constructor property, some of them interesting, others not so much; for now we will not delve into those uses since it isn't relevant to this discussion.
Will not work cross-frame and cross-window
Using .constructor for type checking will break when you want to check the type of objects coming from different window objects, say that of an iframe or a popup window. This is because there's a different version of each core type constructor in each `window', i.e.
iframe.contentWindow.Array === Array // false
Using the instanceof operator...
The instanceof operator is a clean way of testing object type as well, but has its own potential issues, just like the constructor property.
var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true
But instanceof fails to work for literal values (because literals are not Objects)
3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false
The literals need to be wrapped in an Object in order for instanceof to work, for example
new Number(3) instanceof Number // true
The .constructor check works fine for literals because the . method invocation implicitly wraps the literals in their respective object type
3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true
Why two dots for the 3? Because Javascript interprets the first dot as a decimal point ;)
Will not work cross-frame and cross-window
instanceof also will not work across different windows, for the same reason as the constructor property check.
Using the name property of the constructor property...
Does not work AT ALL in many cases
Again, see above; it's quite common for constructor to be utterly and completely wrong and useless.
Does NOT work in <IE9
Using myObjectInstance.constructor.name will give you a string containing the name of the constructor function used, but is subject to the caveats about the constructor property that were mentioned earlier.
For IE9 and above, you can monkey-patch in support:
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1] : "";
},
set: function(value) {}
});
}
Updated version from the article in question. This was added 3 months after the article was published, this is the recommended version to use by the article's author Matthew Scharley. This change was inspired by comments pointing out potential pitfalls in the previous code.
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /function\s([^(]{1,})\(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1].trim() : "";
},
set: function(value) {}
});
}
Using Object.prototype.toString
It turns out, as this post details, you can use Object.prototype.toString - the low level and generic implementation of toString - to get the type for all built-in types
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
One could write a short helper function such as
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
to remove the cruft and get at just the type name
type('abc') // String
However, it will return Object for all user-defined types.
Caveats for all...
All of these are subject to one potential problem, and that is the question of how the object in question was constructed. Here are various ways of building objects and the values that the different methods of type checking will return:
// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == "Foo"); // true
// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // false
(obj.constructor.name == "Foo"); // false
// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object); // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == ""); // true
// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == ""); // true
// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object); // true
(obj.constructor == Object); // true
(obj.constructor.name == "Object"); // true
While not all permutations are present in this set of examples, hopefully there are enough to provide you with an idea about how messy things might get depending on your needs. Don't assume anything, if you don't understand exactly what you are after, you may end up with code breaking where you don't expect it to because of a lack of grokking the subtleties.
NOTE:
Discussion of the typeof operator may appear to be a glaring omission, but it really isn't useful in helping to identify whether an object is a given type, since it is very simplistic. Understanding where typeof is useful is important, but I don't currently feel that it is terribly relevant to this discussion. My mind is open to change though. :)
Jason Bunting's answer gave me enough of a clue to find what I needed:
<<Object instance>>.constructor.name
So, for example, in the following piece of code:
function MyObject() {}
var myInstance = new MyObject();
myInstance.constructor.name would return "MyObject".
A little trick I use:
function Square(){
this.className = "Square";
this.corners = 4;
}
var MySquare = new Square();
console.log(MySquare.className); // "Square"
Update
To be precise, I think OP asked for a function that retrieves the constructor name for a particular object. In terms of Javascript, object does not have a type but is a type of and in itself. However, different objects can have different constructors.
Object.prototype.getConstructorName = function () {
var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
var cname = str.match(/function\s(\w*)/)[1];
var aliases = ["", "anonymous", "Anonymous"];
return aliases.indexOf(cname) > -1 ? "Function" : cname;
}
new Array().getConstructorName(); // returns "Array"
(function () {})().getConstructorName(); // returns "Function"
 
Note: the below example is deprecated.
A blog post linked by Christian Sciberras contains a good example on how to do it. Namely, by extending the Object prototype:
if (!Object.prototype.getClassName) {
Object.prototype.getClassName = function () {
return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1];
}
}
var test = [1,2,3,4,5];
alert(test.getClassName()); // returns Array
Using Object.prototype.toString
It turns out, as this post details, you can use Object.prototype.toString - the low level and generic implementation of toString - to get the type for all built-in types
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
One could write a short helper function such as
function type(obj){
return Object.prototype.toString.call(obj]).match(/\s\w+/)[0].trim()
}
return [object String] as String
return [object Number] as Number
return [object Object] as Object
return [object Undefined] as Undefined
return [object Function] as Function
You should use somevar.constructor.name like a:
const getVariableType = a => a.constructor.name.toLowerCase();
const d = new Date();
const res1 = getVariableType(d); // 'date'
const num = 5;
const res2 = getVariableType(num); // 'number'
const fn = () => {};
const res3 = getVariableType(fn); // 'function'
console.log(res1); // 'date'
console.log(res2); // 'number'
console.log(res3); // 'function'
Here is a solution that I have come up with that solves the shortcomings of instanceof. It can check an object's types from cross-windows and cross-frames and doesn't have problems with primitive types.
function getType(o) {
return Object.prototype.toString.call(o).match(/^\[object\s(.*)\]$/)[1];
}
function isInstance(obj, type) {
var ret = false,
isTypeAString = getType(type) == "String",
functionConstructor, i, l, typeArray, context;
if (!isTypeAString && getType(type) != "Function") {
throw new TypeError("type argument must be a string or function");
}
if (obj !== undefined && obj !== null && obj.constructor) {
//get the Function constructor
functionConstructor = obj.constructor;
while (functionConstructor != functionConstructor.constructor) {
functionConstructor = functionConstructor.constructor;
}
//get the object's window
context = functionConstructor == Function ? self : functionConstructor("return window")();
//get the constructor for the type
if (isTypeAString) {
//type is a string so we'll build the context (window.Array or window.some.Type)
for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
context = context[typeArray[i]];
}
} else {
//type is a function so execute the function passing in the object's window
//the return should be a constructor
context = type(context);
}
//check if the object is an instance of the constructor
if (context) {
ret = obj instanceof context;
if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
ret = obj.constructor == context
}
}
}
return ret;
}
isInstance requires two parameters: an object and a type. The real trick to how it works is that it checks if the object is from the same window and if not gets the object's window.
Examples:
isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false
The type argument can also be a callback function which returns a constructor. The callback function will receive one parameter which is the window of the provided object.
Examples:
//"Arguments" type check
var args = (function() {
return arguments;
}());
isInstance(args, function(w) {
return w.Function("return arguments.constructor")();
}); //true
//"NodeList" type check
var nl = document.getElementsByTagName("*");
isInstance(nl, function(w) {
return w.document.getElementsByTagName("bs").constructor;
}); //true
One thing to keep in mind is that IE < 9 does not provide the constructor on all objects so the above test for NodeList would return false and also a isInstance(alert, "Function") would return false.
I was actually looking for a similar thing and came across this question. Here is how I get types: jsfiddle
var TypeOf = function ( thing ) {
var typeOfThing = typeof thing;
if ( 'object' === typeOfThing ) {
typeOfThing = Object.prototype.toString.call( thing );
if ( '[object Object]' === typeOfThing ) {
if ( thing.constructor.name ) {
return thing.constructor.name;
}
else if ( '[' === thing.constructor.toString().charAt(0) ) {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
else {
typeOfThing = thing.constructor.toString().match( /function\s*(\w+)/ );
if ( typeOfThing ) {
return typeOfThing[1];
}
else {
return 'Function';
}
}
}
else {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
}
return typeOfThing.charAt(0).toUpperCase() + typeOfThing.slice(1);
}
Use constructor.name when you can, and regex function when I can't.
Function.prototype.getName = function(){
if (typeof this.name != 'undefined')
return this.name;
else
return /function (.+)\(/.exec(this.toString())[1];
};
The kind() function from Agave.JS will return:
the closest prototype in the inheritance tree
for always-primitive types like 'null' and 'undefined', the primitive name.
It works on all JS objects and primitives, regardless of how they were created, and doesn't have any surprises.
var kind = function(item) {
var getPrototype = function(item) {
return Object.prototype.toString.call(item).slice(8, -1);
};
var kind, Undefined;
if (item === null ) {
kind = 'null';
} else {
if ( item === Undefined ) {
kind = 'undefined';
} else {
var prototype = getPrototype(item);
if ( ( prototype === 'Number' ) && isNaN(item) ) {
kind = 'NaN';
} else {
kind = prototype;
}
}
}
return kind;
};
Examples:
Numbers
kind(37) === 'Number'
kind(3.14) === 'Number'
kind(Math.LN2) === 'Number'
kind(Infinity) === 'Number'
kind(Number(1)) === 'Number'
kind(new Number(1)) === 'Number'
NaN
kind(NaN) === 'NaN'
Strings
kind('') === 'String'
kind('bla') === 'String'
kind(String("abc")) === 'String'
kind(new String("abc")) === 'String'
Booleans
kind(true) === 'Boolean'
kind(false) === 'Boolean'
kind(new Boolean(true)) === 'Boolean'
Arrays
kind([1, 2, 4]) === 'Array'
kind(new Array(1, 2, 3)) === 'Array'
Objects
kind({a:1}) === 'Object'
kind(new Object()) === 'Object'
Dates
kind(new Date()) === 'Date'
Functions
kind(function(){}) === 'Function'
kind(new Function("console.log(arguments)")) === 'Function'
kind(Math.sin) === 'Function'
undefined
kind(undefined) === 'undefined'
null
kind(null) === 'null'
Here is an implementation based on the accepted answer:
/**
* Describes the type of a variable.
*/
class VariableType
{
type;
name;
/**
* Creates a new VariableType.
*
* #param {"undefined" | "null" | "boolean" | "number" | "bigint" | "array" | "string" | "symbol" |
* "function" | "class" | "object"} type the name of the type
* #param {null | string} [name = null] the name of the type (the function or class name)
* #throws {RangeError} if neither <code>type</code> or <code>name</code> are set. If <code>type</code>
* does not have a name (e.g. "number" or "array") but <code>name</code> is set.
*/
constructor(type, name = null)
{
switch (type)
{
case "undefined":
case "null":
case "boolean" :
case "number" :
case "bigint":
case "array":
case "string":
case "symbol":
if (name !== null)
throw new RangeError(type + " may not have a name");
}
this.type = type;
this.name = name;
}
/**
* #return {string} the string representation of this object
*/
toString()
{
let result;
switch (this.type)
{
case "function":
case "class":
{
result = "a ";
break;
}
case "object":
{
result = "an ";
break;
}
default:
return this.type;
}
result += this.type;
if (this.name !== null)
result += " named " + this.name;
return result;
}
}
const functionNamePattern = /^function\s+([^(]+)?\(/;
const classNamePattern = /^class(\s+[^{]+)?{/;
/**
* Returns the type information of a value.
*
* <ul>
* <li>If the input is undefined, returns <code>(type="undefined", name=null)</code>.</li>
* <li>If the input is null, returns <code>(type="null", name=null)</code>.</li>
* <li>If the input is a primitive boolean, returns <code>(type="boolean", name=null)</code>.</li>
* <li>If the input is a primitive number, returns <code>(type="number", name=null)</code>.</li>
* <li>If the input is a primitive or wrapper bigint, returns
* <code>(type="bigint", name=null)</code>.</li>
* <li>If the input is an array, returns <code>(type="array", name=null)</code>.</li>
* <li>If the input is a primitive string, returns <code>(type="string", name=null)</code>.</li>
* <li>If the input is a primitive symbol, returns <code>(type="symbol", null)</code>.</li>
* <li>If the input is a function, returns <code>(type="function", name=the function name)</code>. If the
* input is an arrow or anonymous function, its name is <code>null</code>.</li>
* <li>If the input is a function, returns <code>(type="function", name=the function name)</code>.</li>
* <li>If the input is a class, returns <code>(type="class", name=the name of the class)</code>.
* <li>If the input is an object, returns
* <code>(type="object", name=the name of the object's class)</code>.
* </li>
* </ul>
*
* Please note that built-in types (such as <code>Object</code>, <code>String</code> or <code>Number</code>)
* may return type <code>function</code> instead of <code>class</code>.
*
* #param {object} value a value
* #return {VariableType} <code>value</code>'s type
* #see http://stackoverflow.com/a/332429/14731
* #see isPrimitive
*/
function getTypeInfo(value)
{
if (value === null)
return new VariableType("null");
const typeOfValue = typeof (value);
const isPrimitive = typeOfValue !== "function" && typeOfValue !== "object";
if (isPrimitive)
return new VariableType(typeOfValue);
const objectToString = Object.prototype.toString.call(value).slice(8, -1);
// eslint-disable-next-line #typescript-eslint/ban-types
const valueToString = value.toString();
if (objectToString === "Function")
{
// A function or a constructor
const indexOfArrow = valueToString.indexOf("=>");
const indexOfBody = valueToString.indexOf("{");
if (indexOfArrow !== -1 && (indexOfBody === -1 || indexOfArrow < indexOfBody))
{
// Arrow function
return new VariableType("function");
}
// Anonymous and named functions
const functionName = functionNamePattern.exec(valueToString);
if (functionName !== null && typeof (functionName[1]) !== "undefined")
{
// Found a named function or class constructor
return new VariableType("function", functionName[1].trim());
}
const className = classNamePattern.exec(valueToString);
if (className !== null && typeof (className[1]) !== "undefined")
{
// When running under ES6+
return new VariableType("class", className[1].trim());
}
// Anonymous function
return new VariableType("function");
}
if (objectToString === "Array")
return new VariableType("array");
const classInfo = getTypeInfo(value.constructor);
return new VariableType("object", classInfo.name);
}
function UserFunction()
{
}
function UserClass()
{
}
let anonymousFunction = function()
{
};
let arrowFunction = i => i + 1;
console.log("getTypeInfo(undefined): " + getTypeInfo(undefined));
console.log("getTypeInfo(null): " + getTypeInfo(null));
console.log("getTypeInfo(true): " + getTypeInfo(true));
console.log("getTypeInfo(5): " + getTypeInfo(5));
console.log("getTypeInfo(\"text\"): " + getTypeInfo("text"));
console.log("getTypeInfo(userFunction): " + getTypeInfo(UserFunction));
console.log("getTypeInfo(anonymousFunction): " + getTypeInfo(anonymousFunction));
console.log("getTypeInfo(arrowFunction): " + getTypeInfo(arrowFunction));
console.log("getTypeInfo(userObject): " + getTypeInfo(new UserClass()));
console.log("getTypeInfo(nativeObject): " + getTypeInfo(navigator.mediaDevices.getUserMedia));
We only use the constructor property when we have no other choice.
You can use the instanceof operator to see if an object is an instance of another, but since there are no classes, you can't get a class name.
You can use the "instanceof" operator to determine if an object is an instance of a certain class or not. If you do not know the name of an object's type, you can use its constructor property. The constructor property of objects, is a reference to the function that is used to initialize them. Example:
function Circle (x,y,radius) {
this._x = x;
this._y = y;
this._radius = raduius;
}
var c1 = new Circle(10,20,5);
Now c1.constructor is a reference to the Circle() function.
You can alsow use the typeof operator, but the typeof operator shows limited information. One solution is to use the toString() method of the Object global object. For example if you have an object, say myObject, you can use the toString() method of the global Object to determine the type of the class of myObject. Use this:
Object.prototype.toString.apply(myObject);
Say you have var obj;
If you just want the name of obj's type, like "Object", "Array", or "String",
you can use this:
Object.prototype.toString.call(obj).split(' ')[1].replace(']', '');
The closest you can get is typeof, but it only returns "object" for any sort of custom type. For those, see Jason Bunting.
Edit, Jason's deleted his post for some reason, so just use Object's constructor property.
For of those of you reading this and want a simple solution that works fairly well and has been tested:
const getTypeName = (thing) => {
const name = typeof thing
if (name !== 'object') return name
if (thing instanceof Error) return 'error'
if (!thing) return 'null'
return ({}).toString.call(thing).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
To get insight on why this works, checkout the polyfill documentation for Array.isArray(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#polyfill
If anyone was looking for a solution which is working with jQuery, here is the adjusted wiki code (the original breaks jQuery).
Object.defineProperty(Object.prototype, "getClassName", {
value: function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
}
});
Lodash has many isMethods so if you're using Lodash maybe a mixin like this can be useful:
// Mixin for identifying a Javascript Object
_.mixin({
'identify' : function(object) {
var output;
var isMethods = ['isArguments', 'isArray', 'isArguments', 'isBoolean', 'isDate', 'isArguments',
'isElement', 'isError', 'isFunction', 'isNaN', 'isNull', 'isNumber',
'isPlainObject', 'isRegExp', 'isString', 'isTypedArray', 'isUndefined', 'isEmpty', 'isObject']
this.each(isMethods, function (method) {
if (this[method](object)) {
output = method;
return false;
}
}.bind(this));
return output;
}
});
It adds a method to lodash called "identify" which works as follow:
console.log(_.identify('hello friend')); // isString
Plunker:
http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
Ok, folks I've been slowly building a catch all method for this over some years lol! The trick is to:
Have a mechanism for creating classes.
Have a mechanism for checking all user created classes, primitives and values created/generated by native constructors.
Have a mechanism for extending user created classes into new ones so that the above functionality permeates through your code/application/library/etc..
For an example (or to see how I dealt with the problem) look at the following code on github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js and search for:
classOf =,
classOfIs =, and or
defineSubClass = (without the backticks (`)).
As you can see I have some mechanisms in place to force classOf to always give me the classes/constructors type name regardless of whether it is a primitive, a user defined class, a value created using a native constructor, Null, NaN, etc.. For every single javascript value I will get it's unique type name from the classOf function. In addition I can pass in actual constructors into sjl.classOfIs to check a value's type in addition to being able to pass in it's type name as well! So for example:
```
// Please forgive long namespaces! I had no idea on the impact until after using them for a while (they suck haha)
var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
constructor: function SomeCustomClass () {},
// ...
}),
HelloIterator = sjl.ns.stdlib.Iterator.extend(
function HelloIterator () {},
{ /* ... methods here ... */ },
{ /* ... static props/methods here ... */ }
),
helloIt = new HelloIterator();
sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`
var someString = 'helloworld';
sjl.classOfIs(someString, String) === true; // `true`
sjl.classOfIs(99, Number) === true; // true
sjl.classOf(NaN) === 'NaN'; // true
sjl.classOf(new Map()) === 'Map';
sjl.classOf(new Set()) === 'Set';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`
// etc..
// Also optionally the type you want to check against could be the type's name
sjl.classOfIs(['a', 'b', 'c'], 'Array') === true; // `true`!
sjl.classOfIs(helloIt, 'HelloIterator') === true; // `true`!
```
If you are interested in reading more on how I use the setup mentioned above take a look at the repo: https://github.com/elycruz/sjljs
Also books with content on the subject:
- "JavaScript Patterns" by Stoyan Stefanov.
- "Javascript - The Definitive Guide." by David Flanagan.
- and many others.. (search le` web).
Also you can quickly test the features I'm talking about here:
- http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (also the 0.5.18 path in the url has the sources from github on there minus the node_modules and such).
Happy Coding!
Fairly Simple!
My favorite method to get type of anything in JS
function getType(entity){
var x = Object.prototype.toString.call(entity)
return x.split(" ")[1].split(']')[0].toLowerCase()
}
my favorite method to check type of anything in JS
function checkType(entity, type){
return getType(entity) === type
}
Use class.name. This also works with function.name.
class TestA {}
console.log(TestA.name); // "TestA"
function TestB() {}
console.log(TestB.name); // "TestB"

Javascript : Seems like typeof doesn't work

I want to set a Value in a javascript object only when it is not set. My (test) function looks like:
var test = function(){
this.value = {};
this.setValue = function(seperator, newValue){
console.log((this.value[seperator] === "undefined")); //Why both times false?
if(typeof(this.value[seperator] === "undefined")){
this.value[seperator] = newValue;
}else{
//noop
}
console.log(this.value[seperator]);
}
}
var blubb = new test();
blubb .setValue("foo","bar");
blubb .setValue("foo","notme");
in the js console it returns
false
bar
false
notme
Can someone tell me why both time my test of "undefined" told me that is not defined?
thanks in advance
Because undefined in JS is not a string, it's a property of global object and you comparing by type using ===.
=== will compare not only values but their types too:
1 === "1" // false
1 == "1" // true
Try this:
console.log(( typeof this.value[seperator] === "undefined"));
typeof operator transforms variable type to string and only then you can check if your variable is equal to string undefined.
In your second piece of code:
if(typeof(this.value[seperator] === "undefined")){
you use typeof operator outside of the variable so your code first checks if this.value[seperator] === "undefined" then it returns false to you and then you check by "typeof false", it will return boolean for you.
In final step your code converts to:
if( "boolean" ){
And this is always true as string is not empty.
Short answer:
"undefined" !== undefined
Check for undefined instead.
> var foo = { foo: 'foo' };
> foo['bar']
undefined
> typeof(foo['bar'])
"undefined"
Also note that typeof(this.value[seperator] === "undefined") means typeof(boolean) as it'd first evaluate your expression (this.value[seperator] === "undefined") and then get the type of that.
You probably meant typeof(this.value[seperator]) === "undefined".
Your brackets are in the wrong place in this line:
if(typeof(this.value[seperator] === "undefined")){
You're doing the typeof of (this.value[seperator] === "undefined") - that's a boolean condition (will return true or false) so I'd expect typeof to give you "boolean". Then your if statements condition is the string "boolean" which, since it's not zero length, is considered true in JavaScript.
What you wanted is:
if((typeof this.value[seperator]) === "undefined") {

Is there a standard function to check for null, undefined, or blank variables in JavaScript?

Is there a universal JavaScript function that checks that a variable has a value and ensures that it's not undefined or null? I've got this code, but I'm not sure if it covers all cases:
function isEmpty(val){
return (val === undefined || val == null || val.length <= 0) ? true : false;
}
You can just check if the variable has a truthy value or not. That means
if (value) {
// do something..
}
will evaluate to true if value is not:
null
undefined
NaN
empty string ("")
0
false
The above list represents all possible falsy values in ECMA-/Javascript. Find it in the specification at the ToBoolean section.
Furthermore, if you do not know whether a variable exists (that means, if it was declared) you should check with the typeof operator. For instance
if (typeof foo !== 'undefined') {
// foo could get resolved and it's defined
}
If you can be sure that a variable is declared at least, you should directly check if it has a truthy value like shown above.
The verbose method to check if value is undefined or null is:
return value === undefined || value === null;
You can also use the == operator but this expects one to know all the rules:
return value == null; // also returns true if value is undefined
function isEmpty(value){
return (value == null || value.length === 0);
}
This will return true for
undefined // Because undefined == null
null
[]
""
and zero argument functions since a function's length is the number of declared parameters it takes.
To disallow the latter category, you might want to just check for blank strings
function isEmpty(value){
return (value == null || value === '');
}
Null or whitespace
function isEmpty(value){
return (value == null || value.trim().length === 0);
}
This is the safest check and I haven't seen it posted here exactly like that:
if (typeof value !== 'undefined' && value) {
//deal with value'
};
It will cover cases where value was never defined, and also any of these:
null
undefined (value of undefined is not the same as a parameter that was never defined)
0
"" (empty string)
false
NaN
Edited: Changed to strict equality (!==) because it's the norm by now ;)
You may find the following function useful:
function typeOf(obj) {
return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
Or in ES7 (comment if further improvements)
function typeOf(obj) {
const { toString } = Object.prototype;
const stringified = obj::toString();
const type = stringified.split(' ')[1].slice(0, -1);
return type.toLowerCase();
}
Results:
typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map
"Note that the bind operator (::) is not part of ES2016 (ES7) nor any later edition of the ECMAScript standard at all. It's currently a stage 0 (strawman) proposal for being introduced to the language." – Simon Kjellberg. the author wishes to add his support for this beautiful proposal to receive royal ascension.
A solution I like a lot:
Let's define that a blank variable is null, or undefined, or if it has length, it is zero, or if it is an object, it has no keys:
function isEmpty (value) {
return (
// null or undefined
(value == null) ||
// has length and it's zero
(value.hasOwnProperty('length') && value.length === 0) ||
// is an Object and has no keys
(value.constructor === Object && Object.keys(value).length === 0)
)
}
Returns:
true: undefined, null, "", [], {}
false: true, false, 1, 0, -1, "foo", [1, 2, 3], { foo: 1 }
This condition check
if (!!foo) {
//foo is defined
}
is all you need.
Take a look at the new ECMAScript Nullish coalescing operator
You can think of this feature - the ?? operator - as a way to “fall back” to a default value when dealing with null or undefined.
let x = foo ?? bar();
Again, the above code is equivalent to the following.
let x = (foo !== null && foo !== undefined) ? foo : bar();
The first answer with best rating is wrong. If value is undefined it will throw an exception in modern browsers. You have to use:
if (typeof(value) !== "undefined" && value)
or
if (typeof value !== "undefined" && value)
! check for empty strings (""), null, undefined, false and the number 0 and NaN. Say, if a string is empty var name = "" then console.log(!name) returns true.
function isEmpty(val){
return !val;
}
this function will return true if val is empty, null, undefined, false, the number 0 or NaN.
OR
According to your problem domain you can just use like !val or !!val.
You are a bit overdoing it. To check if a variable is not given a value, you would only need to check against undefined and null.
function isEmpty(value){
return (typeof value === "undefined" || value === null);
}
This is assuming 0, "", and objects(even empty object and array) are valid "values".
Vacuousness
I don't recommend trying to define or use a function which computes whether any value in the whole world is empty. What does it really mean to be "empty"? If I have let human = { name: 'bob', stomach: 'empty' }, should isEmpty(human) return true? If I have let reg = new RegExp('');, should isEmpty(reg) return true? What about isEmpty([ null, null, null, null ]) - this list only contains emptiness, so is the list itself empty? I want to put forward here some notes on "vacuousness" (an intentionally obscure word, to avoid pre-existing associations) in javascript - and I want to argue that "vacuousness" in javascript values should never be dealt with generically.
Truthiness/Falsiness
For deciding how to determine the "vacuousness" of values, we need to accomodate javascript's inbuilt, inherent sense of whether values are "truthy" or "falsy". Naturally, null and undefined are both "falsy". Less naturally, the number 0 (and no other number except NaN) is also "falsy". Least naturally: '' is falsy, but [] and {} (and new Set(), and new Map()) are truthy - although they all seem equally vacuous!
Null vs Undefined
There is also some discussion concerning null vs undefined - do we really need both in order to express vacuousness in our programs? I personally avoid ever having undefined appear in my code. I always use null to signify "vacuousness". Again, though, we need to accomodate javascript's inherent sense of how null and undefined differ:
Trying to access a non-existent property gives undefined
Omitting a parameter when calling a function results in that parameter receiving undefined:
let f = a => a;
console.log(f('hi'));
console.log(f());
Parameters with default values receive the default only when given undefined, not null:
let f = (v='hello') => v;
console.log(f(null));
console.log(f(undefined));
To me, null is an explicit signifier of vacuousness; "something that could have been filled in was intentionally left blank".
Really undefined is a necessary complication that allows some js features to exist, but in my opinion it should always be left behind the scenes; not interacted with directly. We can think of undefined as, for example, javascript's mechanic for implementing default function arguments. If you refrain from supplying an argument to a function it will receive a value of undefined instead. And a default value will be applied to a function argument if that argument was initially set to undefined. In this case undefined is the linchpin of default function arguments, but it stays in the background: we can achieve default argument functionality without ever referring to undefined:
This is a bad implementation of default arguments as it interacts directly with undefined:
let fnWithDefaults = arg => {
if (arg === undefined) arg = 'default';
...
};
This is a good implementation:
let fnWithDefaults = (arg='default') => { ... };
This is a bad way to accept the default argument:
fnWithDefaults(undefined);
Simply do this instead:
fnWithDefaults();
By the way: do you have a function with multiple arguments, and you want to provide some arguments while accepting defaults for others?
E.g.:
let fnWithDefaults = (a=1, b=2, c=3, d=4) => console.log(a, b, c, d);
If you want to provide values for a and d and accepts defaults for the others what to do? This seems wrong:
fnWithDefaults(10, undefined, undefined, 40);
The answer is: refactor fnWithDefaults to accept a single object:
let fnWithDefaults = ({ a=1, b=2, c=3, d=4 }={}) => console.log(a, b, c, d);
fnWithDefaults({ a: 10, d: 40 }); // Now this looks really nice! (And never talks about "undefined")
Non-generic Vacuousness
I believe that vacuousness should never be dealt with in a generic fashion. We should instead always have the rigour to get more information about our data before determining if it is vacuous - I mainly do this by checking what type of data I'm dealing with:
let isType = (value, Cls) => {
// Intentional use of loose comparison operator detects `null`
// and `undefined`, and nothing else!
return value != null && Object.getPrototypeOf(value).constructor === Cls;
};
Note that this function ignores inheritance - it expects value to be a direct instance of Cls, and not an instance of a subclass of Cls. I avoid instanceof for two main reasons:
([] instanceof Object) === true ("An Array is an Object")
('' instanceof String) === false ("A String is not a String")
Note that Object.getPrototypeOf is used to avoid an (obscure) edge-case such as let v = { constructor: String }; The isType function still returns correctly for isType(v, String) (false), and isType(v, Object) (true).
Overall, I recommend using this isType function along with these tips:
Minimize the amount of code processing values of unknown type. E.g., for let v = JSON.parse(someRawValue);, our v variable is now of unknown type. As early as possible, we should limit our possibilities. The best way to do this can be by requiring a particular type: e.g. if (!isType(v, Array)) throw new Error('Expected Array'); - this is a really quick and expressive way to remove the generic nature of v, and ensure it's always an Array. Sometimes, though, we need to allow v to be of multiple types. In those cases, we should create blocks of code where v is no longer generic, as early as possible:
if (isType(v, String)) {
/* v isn't generic in this block - It's a String! */
} else if (isType(v, Number)) {
/* v isn't generic in this block - It's a Number! */
} else if (isType(v, Array)) {
/* v isn't generic in this block - it's an Array! */
} else {
throw new Error('Expected String, Number, or Array');
}
Always use "whitelists" for validation. If you require a value to be, e.g., a String, Number, or Array, check for those 3 "white" possibilities, and throw an Error if none of the 3 are satisfied. We should be able to see that checking for "black" possibilities isn't very useful: Say we write if (v === null) throw new Error('Null value rejected'); - this is great for ensuring that null values don't make it through, but if a value does make it through, we still know hardly anything about it. A value v which passes this null-check is still VERY generic - it's anything but null! Blacklists hardly dispell generic-ness.
Unless a value is null, never consider "a vacuous value". Instead, consider "an X which is vacuous". Essentially, never consider doing anything like if (isEmpty(val)) { /* ... */ } - no matter how that isEmpty function is implemented (I don't want to know...), it isn't meaningful! And it's way too generic! Vacuousness should only be calculated with knowledge of val's type. Vacuousness-checks should look like this:
"A string, with no chars":
if (isType(val, String) && val.length === 0) ...
"An Object, with 0 props": if (isType(val, Object) && Object.entries(val).length === 0) ...
"A number, equal or less than zero": if (isType(val, Number) && val <= 0) ...
"An Array, with no items": if (isType(val, Array) && val.length === 0) ...
The only exception is when null is used to signify certain functionality. In this case it's meaningful to say: "A vacuous value": if (val === null) ...
The probably shortest answer is
val==null || val==''
if you change rigth side to val==='' then empty array will give false. Proof
function isEmpty(val){
return val==null || val==''
}
// ------------
// TEST
// ------------
var log = (name,val) => console.log(`${name} -> ${isEmpty(val)}`);
log('null', null);
log('undefined', undefined);
log('NaN', NaN);
log('""', "");
log('{}', {});
log('[]', []);
log('[1]', [1]);
log('[0]', [0]);
log('[[]]', [[]]);
log('true', true);
log('false', false);
log('"true"', "true");
log('"false"', "false");
log('Infinity', Infinity);
log('-Infinity', -Infinity);
log('1', 1);
log('0', 0);
log('-1', -1);
log('"1"', "1");
log('"0"', "0");
log('"-1"', "-1");
// "void 0" case
console.log('---\n"true" is:', true);
console.log('"void 0" is:', void 0);
log(void 0,void 0); // "void 0" is "undefined" - so we should get here TRUE
More details about == (source here)
BONUS: Reason why === is more clear than ==
To write clear and easy
understandable code, use explicite list of accepted values
val===undefined || val===null || val===''|| (Array.isArray(val) && val.length===0)
function isEmpty(val){
return val===undefined || val===null || val==='' || (Array.isArray(val) && val.length===0)
}
// ------------
// TEST
// ------------
var log = (name,val) => console.log(`${name} -> ${isEmpty(val)}`);
log('null', null);
log('undefined', undefined);
log('NaN', NaN);
log('""', "");
log('{}', {});
log('[]', []);
log('[1]', [1]);
log('[0]', [0]);
log('[[]]', [[]]);
log('true', true);
log('false', false);
log('"true"', "true");
log('"false"', "false");
log('Infinity', Infinity);
log('-Infinity', -Infinity);
log('1', 1);
log('0', 0);
log('-1', -1);
log('"1"', "1");
log('"0"', "0");
log('"-1"', "-1");
// "void 0" case
console.log('---\n"true" is:', true);
console.log('"void 0" is:', void 0);
log(void 0,void 0); // "void 0" is "undefined" - so we should get here TRUE
Here's mine - returns true if value is null, undefined, etc or blank (ie contains only blank spaces):
function stringIsEmpty(value) {
return value ? value.trim().length == 0 : true;
}
If you prefer plain javascript try this:
/**
* Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
* length of `0` and objects with no own enumerable properties are considered
* "empty".
*
* #static
* #memberOf _
* #category Objects
* #param {Array|Object|string} value The value to inspect.
* #returns {boolean} Returns `true` if the `value` is empty, else `false`.
* #example
*
* _.isEmpty([1, 2, 3]);
* // => false
*
* _.isEmpty([]);
* // => true
*
* _.isEmpty({});
* // => true
*
* _.isEmpty('');
* // => true
*/
function isEmpty(value) {
if (!value) {
return true;
}
if (isArray(value) || isString(value)) {
return !value.length;
}
for (var key in value) {
if (hasOwnProperty.call(value, key)) {
return false;
}
}
return true;
}
Otherwise, if you are already using underscore or lodash, try:
_.isEmpty(value)
return val || 'Handle empty variable'
is a really nice and clean way to handle it in a lot of places, can also be used to assign variables
const res = val || 'default value'
If the variable hasn't been declared, you wont be able to test for undefined using a function because you will get an error.
if (foo) {}
function (bar) {}(foo)
Both will generate an error if foo has not been declared.
If you want to test if a variable has been declared you can use
typeof foo != "undefined"
if you want to test if foo has been declared and it has a value you can use
if (typeof foo != "undefined" && foo) {
//code here
}
You could use the nullish coalescing operator ?? to check for null and undefined values. See the MDN Docs
null ?? 'default string'; // returns "default string"
0 ?? 42; // returns 0
(null || undefined) ?? "foo"; // returns "foo"
To check Default Value
function typeOfVar (obj) {
return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}
function isVariableHaveDefaltVal(variable) {
if ( typeof(variable) === 'string' ) { // number, boolean, string, object
console.log(' Any data Between single/double Quotes is treated as String ');
return (variable.trim().length === 0) ? true : false;
}else if ( typeof(variable) === 'boolean' ) {
console.log('boolean value with default value \'false\'');
return (variable === false) ? true : false;
}else if ( typeof(variable) === 'undefined' ) {
console.log('EX: var a; variable is created, but has the default value of undefined.');
return true;
}else if ( typeof(variable) === 'number' ) {
console.log('number : '+variable);
return (variable === 0 ) ? true : false;
}else if ( typeof(variable) === 'object' ) {
// -----Object-----
if (typeOfVar(variable) === 'array' && variable.length === 0) {
console.log('\t Object Array with length = ' + [].length); // Object.keys(variable)
return true;
}else if (typeOfVar(variable) === 'string' && variable.length === 0 ) {
console.log('\t Object String with length = ' + variable.length);
return true;
}else if (typeOfVar(variable) === 'boolean' ) {
console.log('\t Object Boolean = ' + variable);
return (variable === false) ? true : false;
}else if (typeOfVar(variable) === 'number' ) {
console.log('\t Object Number = ' + variable);
return (variable === 0 ) ? true : false;
}else if (typeOfVar(variable) === 'regexp' && variable.source.trim().length === 0 ) {
console.log('\t Object Regular Expression : ');
return true;
}else if (variable === null) {
console.log('\t Object null value');
return true;
}
}
return false;
}
var str = "A Basket For Every Occasion";
str = str.replace(/\s/g, "-");
//The "g" flag in the regex will cause all spaces to get replaced.
check Result:
isVariableHaveDefaltVal(' '); // string
isVariableHaveDefaltVal(false); // boolean
var a;
isVariableHaveDefaltVal(a);
isVariableHaveDefaltVal(0); // number
isVariableHaveDefaltVal(parseInt('')); // NAN isNAN(' '); - true
isVariableHaveDefaltVal(null);
isVariableHaveDefaltVal([]);
isVariableHaveDefaltVal(/ /);
isVariableHaveDefaltVal(new Object(''));
isVariableHaveDefaltVal(new Object(false));
isVariableHaveDefaltVal(new Object(0));
typeOfVar( function() {} );
I used #Vix function() to check the object of which type.
using instansof «
var prototypes_or_Literals = function (obj) {
switch (typeof(obj)) {
// object prototypes
case 'object':
if (obj instanceof Array)
return '[object Array]';
else if (obj instanceof Date)
return '[object Date]';
else if (obj instanceof RegExp)
return '[object regexp]';
else if (obj instanceof String)
return '[object String]';
else if (obj instanceof Number)
return '[object Number]';
else
return 'object';
// object literals
default:
return typeof(obj);
}
};
output test «
prototypes_or_Literals( '' ) // "string"
prototypes_or_Literals( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]"
function isEmpty(obj) {
if (typeof obj == 'number') return false;
else if (typeof obj == 'string') return obj.length == 0;
else if (Array.isArray(obj)) return obj.length == 0;
else if (typeof obj == 'object') return obj == null || Object.keys(obj).length == 0;
else if (typeof obj == 'boolean') return false;
else return !obj;
}
In ES6 with trim to handle whitespace strings:
const isEmpty = value => {
if (typeof value === 'number') return false
else if (typeof value === 'string') return value.trim().length === 0
else if (Array.isArray(value)) return value.length === 0
else if (typeof value === 'object') return value == null || Object.keys(value).length === 0
else if (typeof value === 'boolean') return false
else return !value
}
It may be usefull.
All values in array represent what you want to be (null, undefined or another things) and you search what you want in it.
var variablesWhatILookFor = [null, undefined, ''];
variablesWhatILookFor.indexOf(document.DocumentNumberLabel) > -1
If you are using TypeScript and don't want to account for "values those are false" then this is the solution for you:
First: import { isNullOrUndefined } from 'util';
Then: isNullOrUndefined(this.yourVariableName)
Please Note: As mentioned below this is now deprecated, use value === undefined || value === null instead. ref.
Try With Different Logic. You can use bellow code for check all four(4) condition for validation like not null, not blank, not undefined and not zero only use this code (!(!(variable))) in javascript and jquery.
function myFunction() {
var data; //The Values can be like as null, blank, undefined, zero you can test
if(!(!(data)))
{
alert("data "+data);
}
else
{
alert("data is "+data);
}
}
The optional chaining operator provides a way to simplify accessing values through connected objects when it's possible that a reference or function may be undefined or null.
let customer = {
name: "Carl",
details: {
age: 82,
location: "Paradise Falls" // detailed address is unknown
}
};
let customerCity = customer.details?.address?.city;
The nullish coalescing operator may be used after optional chaining in order to build a default value when none was found:
let customer = {
name: "Carl",
details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city
function isEmpty(val){
return !val;
}
but this solution is over-engineered, if you dont'want to modify the function later for busines-model needings, then is cleaner to use it directly in code:
if(!val)...
var myNewValue = myObject && myObject.child && myObject.child.myValue;
This will never throw an error. If myObject, child, or myValue is null then myNewValue will be null. No errors will be thrown
For everyone coming here for having similar question, the following works great and I have it in my library the last years:
(function(g3, $, window, document, undefined){
g3.utils = g3.utils || {};
/********************************Function type()********************************
* Returns a lowercase string representation of an object's constructor.
* #module {g3.utils}
* #function {g3.utils.type}
* #public
* #param {Type} 'obj' is any type native, host or custom.
* #return {String} Returns a lowercase string representing the object's
* constructor which is different from word 'object' if they are not custom.
* #reference http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
* http://stackoverflow.com/questions/3215046/differentiating-between-arrays-and-hashes-in-javascript
* http://javascript.info/tutorial/type-detection
*******************************************************************************/
g3.utils.type = function (obj){
if(obj === null)
return 'null';
else if(typeof obj === 'undefined')
return 'undefined';
return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
};
}(window.g3 = window.g3 || {}, jQuery, window, document));
If you want to avoid getting true if the value is any of the following, according to jAndy's answer:
null
undefined
NaN
empty string ("")
0
false
One possible solution that might avoid getting truthy values is the following:
function isUsable(valueToCheck) {
if (valueToCheck === 0 || // Avoid returning false if the value is 0.
valueToCheck === '' || // Avoid returning false if the value is an empty string.
valueToCheck === false || // Avoid returning false if the value is false.
valueToCheck) // Returns true if it isn't null, undefined, or NaN.
{
return true;
} else {
return false;
}
}
It would be used as follows:
if (isUsable(x)) {
// It is usable!
}
// Make sure to avoid placing the logical NOT operator before the parameter (isUsable(!x)) and instead, use it before the function, to check the returned value.
if (!isUsable(x)) {
// It is NOT usable!
}
In addition to those scenarios, you may want to return false if the object or array is empty:
Object: {} (Using ECMA 7+)
Array: [] (Using ECMA 5+)
You would go about it this way:
function isEmptyObject(valueToCheck) {
if(typeof valueToCheck === 'object' && !Object.keys(valueToCheck).length){
// Object is empty!
return true;
} else {
// Object is not empty!
return false;
}
}
function isEmptyArray(valueToCheck) {
if(Array.isArray(valueToCheck) && !valueToCheck.length) {
// Array is empty!
return true;
} else {
// Array is not empty!
return false;
}
}
If you wish to check for all whitespace strings (" "), you may do the following:
function isAllWhitespace(){
if (valueToCheck.match(/^ *$/) !== null) {
// Is all whitespaces!
return true;
} else {
// Is not all whitespaces!
return false;
}
}
Note: hasOwnProperty returns true for empty strings, 0, false, NaN, null, and undefined, if the variable was declared as any of them, so it might not be the best to use. The function may be modified to use it to show that it was declared, but is not usable.
Code on GitHub
const isEmpty = value => (
(!value && value !== 0 && value !== false)
|| (Array.isArray(value) && value.length === 0)
|| (isObject(value) && Object.keys(value).length === 0)
|| (typeof value.size === 'number' && value.size === 0)
// `WeekMap.length` is supposed to exist!?
|| (typeof value.length === 'number'
&& typeof value !== 'function' && value.length === 0)
);
// Source: https://levelup.gitconnected.com/javascript-check-if-a-variable-is-an-object-and-nothing-else-not-an-array-a-set-etc-a3987ea08fd7
const isObject = value =>
Object.prototype.toString.call(value) === '[object Object]';
Poor man's tests 😁
const test = () => {
const run = (label, values, expected) => {
const length = values.length;
console.group(`${label} (${length} tests)`);
values.map((v, i) => {
console.assert(isEmpty(v) === expected, `${i}: ${v}`);
});
console.groupEnd();
};
const empty = [
null, undefined, NaN, '', {}, [],
new Set(), new Set([]), new Map(), new Map([]),
];
const notEmpty = [
' ', 'a', 0, 1, -1, false, true, {a: 1}, [0],
new Set([0]), new Map([['a', 1]]),
new WeakMap().set({}, 1),
new Date(), /a/, new RegExp(), () => {},
];
const shouldBeEmpty = [
{undefined: undefined}, new Map([[]]),
];
run('EMPTY', empty, true);
run('NOT EMPTY', notEmpty, false);
run('SHOULD BE EMPTY', shouldBeEmpty, true);
};
Test results:
EMPTY (10 tests)
NOT EMPTY (16 tests)
SHOULD BE EMPTY (2 tests)
Assertion failed: 0: [object Object]
Assertion failed: 1: [object Map]
function notEmpty(value){
return (typeof value !== 'undefined' && value.trim().length);
}
it will also check white spaces (' ') along with following:
null ,undefined ,NaN ,empty ,string ("") ,0 ,false

Check if a variable is a string in JavaScript

How can I determine whether a variable is a string or something else in JavaScript?
This is what works for me:
if (typeof myVar === 'string' || myVar instanceof String)
// it's a string
else
// it's something else
You can use typeof operator:
var booleanValue = true;
var numericalValue = 354;
var stringValue = "This is a String";
var stringObject = new String("This is a String Object");
console.log(typeof booleanValue) // displays "boolean"
console.log(typeof numericalValue) // displays "number"
console.log(typeof stringValue) // displays "string"
console.log(typeof stringObject) // displays "object"
Example from this webpage. (Example was slightly modified though).
This won't work as expected in the case of strings created with new String(), but this is seldom used and recommended against[1][2]. See the other answers for how to handle these, if you so desire.
The Google JavaScript Style Guide says to never use primitive object wrappers.
Douglas Crockford recommended that primitive object wrappers be deprecated.
Since 580+ people have voted for an incorrect answer, and 800+ have voted for a working but shotgun-style answer, I thought it might be worth redoing my answer in a simpler form that everybody can understand.
function isString(x) {
return Object.prototype.toString.call(x) === "[object String]"
}
Or, inline (I have an UltiSnip setup for this):
Object.prototype.toString.call(myVar) === "[object String]"
FYI, Pablo Santa Cruz's answer is wrong, because typeof new String("string") is object
DRAX's answer is accurate and functional and should be the correct answer (since Pablo Santa Cruz is most definitely incorrect, and I won't argue against the popular vote.)
However, this answer is also definitely correct, and actually the best answer (except, perhaps, for the suggestion of using lodash/underscore). disclaimer: I contributed to the lodash 4 codebase.
My original answer (which obviously flew right over a lot of heads) follows:
I transcoded this from underscore.js:
['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'].forEach(
function(name) {
window['is' + name] = function(obj) {
return toString.call(obj) == '[object ' + name + ']';
};
});
That will define isString, isNumber, etc.
In Node.js, this can be implemented as a module:
module.exports = [
'Arguments',
'Function',
'String',
'Number',
'Date',
'RegExp'
].reduce( (obj, name) => {
obj[ 'is' + name ] = x => toString.call(x) == '[object ' + name + ']';
return obj;
}, {});
[edit]: Object.prototype.toString.call(x) works to delineate between functions and async functions as well:
const fn1 = () => new Promise((resolve, reject) => setTimeout(() => resolve({}), 1000))
const fn2 = async () => ({})
console.log('fn1', Object.prototype.toString.call(fn1))
console.log('fn2', Object.prototype.toString.call(fn2))
I recommend using the built-in functions from jQuery or lodash/Underscore. They're simpler to use and easier to read.
Either function will handle the case DRAX mentioned... that is, they both check if (A) the variable is a string literal or (B) it's an instance of the String object. In either case, these functions correctly identify the value as being a string.
lodash / Underscore.js
if(_.isString(myVar))
//it's a string
else
//it's something else
jQuery
if($.type(myVar) === "string")
//it's a string
else
//it's something else
See lodash Documentation for _.isString() for more details.
See jQuery Documentation for $.type() for more details.
Edit: The current way to do it is typeof value === 'string'. For example:
const str = 'hello';
if (typeof str === 'string') { ... }
Below has been deprecated since node v4.
If you work on the node.js environment, you can simply use the built-in function isString in utils.
const util = require('util');
if (util.isString(myVar)) {}
function isString (obj) {
return (Object.prototype.toString.call(obj) === '[object String]');
}
I saw that here:
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
Best way:
var s = 'String';
var a = [1,2,3];
var o = {key: 'val'};
(s.constructor === String) && console.log('its a string');
(a.constructor === Array) && console.log('its an array');
(o.constructor === Object) && console.log('its an object');
(o.constructor === Number || s.constructor === Boolean) && console.log('this won\'t run');
Each of these has been constructed by its appropriate class function, like "new Object()" etc.
Also, Duck-Typing:
"If it looks like a duck, walks like a duck, and smells like a duck - it must be an Array"
Meaning, check its properties.
Hope this helps.
Edit; 12/05/2016
Remember, you can always use combinations of approaches too. Here's an example of using an inline map of actions with typeof:
var type = { 'number': Math.sqrt.bind(Math), ... }[ typeof datum ];
Here's a more 'real world' example of using inline-maps:
function is(datum) {
var isnt = !{ null: true, undefined: true, '': true, false: false, 0: false }[ datum ];
return !isnt;
}
console.log( is(0), is(false), is(undefined), ... ); // >> true true false
This function would use [ custom ] "type-casting" -- rather, "type-/-value-mapping" -- to figure out if a variable actually "exists". Now you can split that nasty hair between null & 0!
Many times you don't even care about its type. Another way to circumvent typing is combining Duck-Type sets:
this.id = "998"; // use a number or a string-equivalent
function get(id) {
if (!id || !id.toString) return;
if (id.toString() === this.id.toString()) http( id || +this.id );
// if (+id === +this.id) ...;
}
Both Number.prototype and String.prototype have a .toString() method. You just made sure that the string-equivalent of the number was the same, and then you made sure that you passed it into the http function as a Number. In other words, we didn't even care what its type was.
Hope that gives you more to work with :)
I can't honestly see why one would not simply use typeof in this case:
if (typeof str === 'string') {
return 42;
}
Yes it will fail against object-wrapped strings (e.g. new String('foo')) but these are widely regarded as a bad practice and most modern development tools are likely to discourage their use. (If you see one, just fix it!)
The Object.prototype.toString trick is something that all front-end developers have been found guilty of doing one day in their careers but don't let it fool you by its polish of clever: it will break as soon as something monkey-patch the Object prototype:
const isString = thing => Object.prototype.toString.call(thing) === '[object String]';
console.log(isString('foo'));
Object.prototype.toString = () => 42;
console.log(isString('foo'));
Performance
Today 2020.09.17 I perform tests on MacOs HighSierra 10.13.6 on Chrome v85, Safari v13.1.2 and Firefox v80 for chosen solutions.
Results
For all browsers (and both test cases)
solutions typeof||instanceof (A, I) and x===x+'' (H) are fast/fastest
solution _.isString (lodash lib) is medium/fast
solutions B and K are slowest
Update: 2020.11.28 I update results for x=123 Chrome column - for solution I there was probably an error value before (=69M too low) - I use Chrome 86.0 to repeat tests.
Details
I perform 2 tests cases for solutions
A
B
C
D
E
F
G
H
I
J
K
L
when variable is string - you can run it HERE
when variable is NOT string - you can run it HERE
Below snippet presents differences between solutions
// https://stackoverflow.com/a/9436948/860099
function A(x) {
return (typeof x == 'string') || (x instanceof String)
}
// https://stackoverflow.com/a/17772086/860099
function B(x) {
return Object.prototype.toString.call(x) === "[object String]"
}
// https://stackoverflow.com/a/20958909/860099
function C(x) {
return _.isString(x);
}
// https://stackoverflow.com/a/20958909/860099
function D(x) {
return $.type(x) === "string";
}
// https://stackoverflow.com/a/16215800/860099
function E(x) {
return x?.constructor === String;
}
// https://stackoverflow.com/a/42493631/860099
function F(x){
return x?.charAt != null
}
// https://stackoverflow.com/a/57443488/860099
function G(x){
return String(x) === x
}
// https://stackoverflow.com/a/19057360/860099
function H(x){
return x === x + ''
}
// https://stackoverflow.com/a/4059166/860099
function I(x) {
return typeof x == 'string'
}
// https://stackoverflow.com/a/28722301/860099
function J(x){
return x === x?.toString()
}
// https://stackoverflow.com/a/58892465/860099
function K(x){
return x && typeof x.valueOf() === "string"
}
// https://stackoverflow.com/a/9436948/860099
function L(x) {
return x instanceof String
}
// ------------------
// PRESENTATION
// ------------------
console.log('Solutions results for different inputs \n\n');
console.log("'abc' Str '' ' ' '1' '0' 1 0 {} [] true false null undef");
let tests = [ 'abc', new String("abc"),'',' ','1','0',1,0,{},[],true,false,null,undefined];
[A,B,C,D,E,F,G,H,I,J,K,L].map(f=> {
console.log(
`${f.name} ` + tests.map(v=> (1*!!f(v)) ).join` `
)})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"></script>
This shippet only presents functions used in performance tests - it not perform tests itself!
And here are example results for chrome
This is a great example of why performance matters:
Doing something as simple as a test for a string can be expensive if not done correctly.
For example, if I wanted to write a function to test if something is a string, I could do it in one of two ways:
1) const isString = str => (Object.prototype.toString.call(str) === '[object String]');
2) const isString = str => ((typeof str === 'string') || (str instanceof String));
Both of these are pretty straight forward, so what could possibly impact performance? Generally speaking, function calls can be expensive, especially if you don't know what's happening inside. In the first example, there is a function call to Object's toString method. In the second example, there are no function calls, as typeof and instanceof are operators. Operators are significantly faster than function calls.
When the performance is tested, example 1 is 79% slower than example 2!
See the tests: https://jsperf.com/isstringtype
I like to use this simple solution:
var myString = "test";
if(myString.constructor === String)
{
//It's a string
}
if (s && typeof s.valueOf() === "string") {
// s is a string
}
Works for both string literals let s = 'blah' and for Object Strings let s = new String('blah')
I find this simple technique useful to type-check for String -
String(x) === x // true, if x is a string
// false in every other case
const test = x =>
console.assert
( String(x) === x
, `not a string: ${x}`
)
test("some string")
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/) // assertion failed
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
The same technique works for Number too -
Number(x) === x // true, if x is a number
// false in every other case
const test = x =>
console.assert
( Number(x) === x
, `not a number: ${x}`
)
test("some string") // assertion failed
test(123)
test(0)
test(/some regex/) // assertion failed
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
And for RegExp -
RegExp(x) === x // true, if x is a regexp
// false in every other case
const test = x =>
console.assert
( RegExp(x) === x
, `not a regexp: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/)
test([ 5, 6 ]) // assertion failed
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
Same for Object -
Object(x) === x // true, if x is an object
// false in every other case
NB, regexps, arrays, and functions are considered objects too.
const test = x =>
console.assert
( Object(x) === x
, `not an object: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/)
test([ 5, 6 ])
test({ a: 1 })
test(x => x + 1)
But, checking for Array is a bit different -
Array.isArray(x) === x // true, if x is an array
// false in every other case
const test = x =>
console.assert
( Array.isArray(x)
, `not an array: ${x}`
)
test("some string") // assertion failed
test(123) // assertion failed
test(0) // assertion failed
test(/some regex/) // assertion failed
test([ 5, 6 ])
test({ a: 1 }) // assertion failed
test(x => x + 1) // assertion failed
This technique does not work for Functions however -
Function(x) === x // always false
For #Faither -
const fmt = JSON.stringify
function test1() {
const a = "1"
const b = 1
console.log(`Number(${fmt(a)}) === ${fmt(b)}`, Number(a) === b) // true
}
function test2() {
const a = "1"
const b = 1
console.log(`Number.isInteger(${fmt(a)})`, Number.isInteger(a)) // false
console.log(`Number.isInteger(${fmt(b)})`, Number.isInteger(b)) // true
}
function test3() {
name = 1 // global name will always be a string
console.log(fmt(name)) // "1"
console.log(`String(${fmt(name)}) === ${fmt(name)}`, String(name) === name) // true
}
function test4() {
const name = 1 // local name
console.log(fmt(name)) // 1
console.log(`String(${fmt(name)}) === ${fmt(name)}`, String(name) === name) // false
}
test1(); test2(); test3(); test4()
Taken from lodash:
function isString(val) {
return typeof val === 'string' || ((!!val && typeof val === 'object') && Object.prototype.toString.call(val) === '[object String]');
}
console.log(isString('hello world!')); // true
console.log(isString(new String('hello world'))); // true
You can use this function to determine the type of anything:
var type = function(obj) {
return Object.prototype.toString.apply(obj).replace(/\[object (.+)\]/i, '$1').toLowerCase();
};
To check if a variable is a string:
type('my string') === 'string' //true
type(new String('my string')) === 'string' //true
type(`my string`) === 'string' //true
type(12345) === 'string' //false
type({}) === 'string' // false
https://codepen.io/patodiblasi/pen/NQXPwY?editors=0012
To check for other types:
type(null) //null
type(undefined) //undefined
type([]) //array
type({}) //object
type(function() {}) //function
type(123) //number
type(new Number(123)) //number
type(/some_regex/) //regexp
type(Symbol("foo")) //symbol
A simple and fast way to test can be using the constructor name attribute.
let x = "abc";
console.log(x.constructor.name === "String"); // true
let y = new String('abc');
console.log(y.constructor.name === "String"); // true
Performance
I also found that this works fine too, and its a lot shorter than the other examples.
if (myVar === myVar + '') {
//its string
} else {
//its something else
}
By concatenating on empty quotes it turns the value into a string. If myVar is already a string then the if statement is successful.
var a = new String('')
var b = ''
var c = []
function isString(x) {
return x !== null && x !== undefined && x.constructor === String
}
console.log(isString(a))
console.log(isString(b))
console.log(isString(c))
The following method will check if any variable is a string (including variables that do not exist).
const is_string = value => {
try {
return typeof value() === 'string';
} catch (error) {
return false;
}
};
let example = 'Hello, world!';
console.log(is_string(() => example)); // true
console.log(is_string(() => variable_doesnt_exist)); // false
This is good enough for me.
WARNING: This is not a perfect solution.
See the bottom of my post.
Object.prototype.isString = function() { return false; };
String.prototype.isString = function() { return true; };
var isString = function(a) {
return (a !== null) && (a !== undefined) && a.isString();
};
And you can use this like below.
//return false
isString(null);
isString(void 0);
isString(-123);
isString(0);
isString(true);
isString(false);
isString([]);
isString({});
isString(function() {});
isString(0/0);
//return true
isString("");
isString(new String("ABC"));
WARNING: This works incorrectly in the case:
//this is not a string
var obj = {
//but returns true lol
isString: function(){ return true; }
}
isString(obj) //should be false, but true
A simple solution would be:
var x = "hello"
if(x === x.toString()){
// it's a string
}else{
// it isn't
}
A Typechecker helper:
function isFromType(variable, type){
if (typeof type == 'string') res = (typeof variable == type.toLowerCase())
else res = (variable.constructor == type)
return res
}
usage:
isFromType('cs', 'string') //true
isFromType('cs', String) //true
isFromType(['cs'], Array) //true
isFromType(['cs'], 'object') //false
Also if you want it to be recursive(like Array that is an Object), you can use instanceof.
(['cs'] instanceof Object //true)
I'm going to go a different route to the rest here, which try to tell if a variable is a specific, or a member of a specific set, of types.
JS is built on ducktyping; if something quacks like a string, we can and should use it like a string.
Is 7 a string? Then why does /\d/.test(7) work?
Is {toString:()=>('hello there')} a string? Then why does ({toString:()=>('hello there')}) + '\ngeneral kenobi!' work?
These aren't questions about should the above work, the point is they do.
So I made a duckyString() function
Below I test many cases not catered for by other answers. For each the code:
sets a string-like variable
runs an identical string operation on it and a real string to compare outputs (proving they can be treated like strings)
converts the string-like to a real string to show you duckyString() to normalise inputs for code that expects real strings
text = 'hello there';
out(text.replace(/e/g, 'E') + ' ' + 'hello there'.replace(/e/g, 'E'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = new String('oh my');
out(text.toUpperCase() + ' ' + 'oh my'.toUpperCase());
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = 368;
out((text + ' is a big number') + ' ' + ('368' + ' is a big number'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
text = ['\uD83D', '\uDE07'];
out(text[1].charCodeAt(0) + ' ' + '😇'[1].charCodeAt(0));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
function Text() { this.math = 7; }; Text.prototype = {toString:function() { return this.math + 3 + ''; }}
text = new Text();
out(String.prototype.match.call(text, '0') + ' ' + text.toString().match('0'));
out('Is string? ' + duckyString(text) + '\t"' + duckyString(text, true) + '"\n');
This is in the same vein as !!x as opposed to x===true and testing if something is array-like instead of necessitating an actual array.
jQuery objects; are they arrays? No. Are they good enough? Yeah, you can run them through Array.prototype functions just fine.
It's this flexibility that gives JS its power, and testing for strings specifically makes your code less interoperable.
The output of the above is:
hEllo thErE hEllo thErE
Is string? true "hello there"
OH MY OH MY
Is string? true "oh my"
368 is a big number 368 is a big number
Is string? true "368"
56839 56839
Is string? true "😇"
0 0
Is string? true "10"
So, it's all about why you want to know if something's a string.
If, like me, you arrived here from google and wanted to see if something was string-like, here's an answer.
It isn't even expensive unless you're working with really long or deeply nested char arrays.
This is because it is all if statements, no function calls like .toString().
Except if you're trying to see if a char array with objects that only have toString()'s or multi-byte characters, in which case there's no other way to check except to make the string, and count characters the bytes make up, respectively
function duckyString(string, normalise, unacceptable) {
var type = null;
if (!unacceptable)
unacceptable = {};
if (string && !unacceptable.chars && unacceptable.to == null)
unacceptable.to = string.toString == Array.prototype.toString;
if (string == null)
;
//tests if `string` just is a string
else if (
!unacceptable.is &&
(typeof string == 'string' || string instanceof String)
)
type = 'is';
//tests if `string + ''` or `/./.test(string)` is valid
else if (
!unacceptable.to &&
string.toString && typeof string.toString == 'function' && string.toString != Object.prototype.toString
)
type = 'to';
//tests if `[...string]` is valid
else if (
!unacceptable.chars &&
(string.length > 0 || string.length == 0)
) {
type = 'chars';
//for each char
for (var index = 0; type && index < string.length; ++index) {
var char = string[index];
//efficiently get its length
var length = ((duckyString(char, false, {to:true})) ?
char :
duckyString(char, true) || {}
).length;
if (length == 1)
continue;
//unicode surrogate-pair support
char = duckyString(char, true);
length = String.prototype[Symbol && Symbol.iterator];
if (!(length = length && length.call(char)) || length.next().done || !length.next().done)
type = null;
}
}
//return true or false if they dont want to auto-convert to real string
if (!(type && normalise))
//return truthy or falsy with <type>/null if they want why it's true
return (normalise == null) ? type != null : type;
//perform conversion
switch (type) {
case 'is':
return string;
case 'to':
return string.toString();
case 'chars':
return Array.from(string).join('');
}
}
Included are options to
ask which method deemed it string-y
exclude methods of string-detection (eg if you dont like .toString())
Here are more tests because I'm a completionist:
out('Edge-case testing')
function test(text, options) {
var result = duckyString(text, false, options);
text = duckyString(text, true, options);
out(result + ' ' + ((result) ? '"' + text + '"' : text));
}
test('');
test(null);
test(undefined);
test(0);
test({length:0});
test({'0':'!', length:'1'});
test({});
test(window);
test(false);
test(['hi']);
test(['\uD83D\uDE07']);
test([['1'], 2, new String(3)]);
test([['1'], 2, new String(3)], {chars:true});
All negative cases seem to be accounted for
This should run on browsers >= IE8
Char arrays with multiple bytes supported on browsers with string iterator support
Output:
Edge-case testing
is ""
null null
null null
to "0"
chars ""
chars "!"
null null
chars ""
to "false"
null null
chars "😇"
chars "123"
to "1,2,3"
Implementation from lodash library v4.0.0
// getTag.js
const toString = Object.prototype.toString;
/**
* Gets the `toStringTag` of `value`.
*
* #private
* #param {*} value The value to query.
* #returns {string} Returns the `toStringTag`.
*/
function getTag(value) {
if (value == null) {
return value === undefined
? "[object Undefined]"
: "[object Null]";
}
return toString.call(value);
}
// isString.js
import getTag from "./getTag.js";
/**
* Checks if `value` is classified as a `String` primitive or object.
*
* #since 0.1.0
* #category Lang
* #param {*} value The value to check.
* #returns {boolean} Returns `true` if `value` is a string, else `false`.
* #example
*
* isString('abc')
* // => true
*
* isString(1)
* // => false
*/
function isString(value) {
const type = typeof value;
return (
type === "string" || (type === "object" &&
value != null &&
!Array.isArray(value) &&
getTag(value) == "[object String]")
);
}
export default isString;
I have a technique that's stupid. But straightforward.
if(maybeAString.toUpperCase)
weHaveAString(maybeAString)
Yeah, it's far from perfect. But it is straightforward.
Just to expand on #DRAX's answer, I'd do this:
function isWhitespaceEmptyString(str)
{
//RETURN:
// = 'true' if 'str' is empty string, null, undefined, or consists of white-spaces only
return str ? !(/\S/.test(str)) : (str === "" || str === null || str === undefined);
}
It will account also for nulls and undefined types, and it will take care of non-string types, such as 0.
A code to have only string without any numbers
isNaN("A") = true;
parseInt("A") = NaN;
isNaN(NaN) = true;
Than we can use isNaN(parseInt()) to have only the string
let ignoreNumbers = "ad123a4m";
let ign = ignoreNumbers.split("").map((ele) => isNaN(parseInt(ele)) ? ele : "").join("");
console.log(ign);
also we can use isFinite() rather than typeof or isNAN()
check this:
var name="somename",trickyName="123", invalidName="123abc";
typeof name == typeof trickyName == typeof invalidName == "string" 🤷‍♀️
isNAN(name)==true
isNAN(trickyName)==false
isNAN(invalidName)==true 👀
where:
isFinite(name) == false
isFinite(trickyName)== true
isFinite(invalidName)== true
so we can do:
if(!isFinite(/*any string*/))
console.log("it is string type for sure")
notice that:
isFinite("asd123")==false
isNAN("asd123")==true
isString() checks whether passed argument is a string or not, using optional chaining and latest standards:
const isString = (value) => {
return value?.constructor === String;
}
I'm not sure if you mean knowing if it's a type string regardless of its contents, or whether it's contents is a number or string, regardless of its type.
So to know if its type is a string, that's already been answered.
But to know based on its contents if its a string or a number, I would use this:
function isNumber(item) {
return (parseInt(item) + '') === item;
}
And for some examples:
isNumber(123); //true
isNumber('123'); //true
isNumber('123a');//false
isNumber(''); //false

Categories