Easier way to pass multiple parameters in a function with javascript - javascript

This is a JavaScript function that determines if arguments are strings
just curious if anyone has a way to simplify this function?
I can't help but think there is since there are so many similarities in the parameters
typeof x === "string"
that there is a way to simplify it. I asked my teachers and they told me they were unaware of any.
function isString(string1, string2, string3) {
if (typeof x === "string" && typeof y === "string" && typeof z === "string")
console.log("Yes!" + x + " " + y + " " + z)
else {
console.log("Nope!")
}
}
isString("String1", "String2", "String3")
I really look forward to reading your responses!
Thanks
-Joe

You might be looking for rest parameters or the arguments object that let you handle an arbitrary amount of arguments, together with looping over them (or using a helper method for that):
function areStrings(...args) {
if (args.every(x => typeof x === "string"))
return "Yes!" + args.join(" ");
else
return "Nope!";
}
console.log(areStrings("String1", "String2", "String3"));
console.log(areStrings(5, "someString"));

you can receive your params as an array o, and the use functional parameter to check:
function isString(...strings) {
if (strings.every(s => typeof s === 'string'))
console.log("They are string")
else
console.log("They are not string")
}

If you want to check if multiple variables are strings, you can use this function:
function isString(...args){
for(var i = 0; i<args.length; i++){
if(typeof args[i] !== 'string'){
return false;
}
}
return true;
}
You can pass as much parameters as you want and the result will be only true if all parameters are strings.
Example:
isString(4) returns false
isString("Hello World") returns true
isString("I am a string", 3, true, "Hello") returns false
isString("Hello World", "Welcome") returns true

Clear answer, simple effective. I come to propose another way of doing things. Arrow function + ternary. More verbose but condense.
(I didn't know every cool :))
var resultAmeliored = (...args) => 'Var: '+args.map(val => val+' is '+typeof val).join(', ');
var areStrings = (...args)=>args.every(s => typeof s === 'string')?true:false;
console.log(areStrings("String1", "String2", "String3"));
//true
console.log(resultAmeliored(5, "someString"));
//"Var: 5 is number, someString is string"

Related

How to check the type of an element in a array in Jacascript [duplicate]

Does anyone know how can I check whether a variable is a number or a string in JavaScript?
If you're dealing with literal notation, and not constructors, you can use typeof:.
typeof "Hello World"; // string
typeof 123; // number
If you're creating numbers and strings via a constructor, such as var foo = new String("foo"), you should keep in mind that typeof may return object for foo.
Perhaps a more foolproof method of checking the type would be to utilize the method found in underscore.js (annotated source can be found here),
var toString = Object.prototype.toString;
_.isString = function (obj) {
return toString.call(obj) == '[object String]';
}
This returns a boolean true for the following:
_.isString("Jonathan"); // true
_.isString(new String("Jonathan")); // true
Best way to do that is using isNaN + type casting:
Updated all-in method:
function isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) }
The same using regex:
function isNumber(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n); }
------------------------
isNumber('123'); // true
isNumber('123abc'); // false
isNumber(5); // true
isNumber('q345'); // false
isNumber(null); // false
isNumber(undefined); // false
isNumber(false); // false
isNumber(' '); // false
The best way I have found is to either check for a method on the string, i.e.:
if (x.substring) {
// do string thing
} else{
// do other thing
}
or if you want to do something with the number check for a number property,
if (x.toFixed) {
// do number thing
} else {
// do other thing
}
This is sort of like "duck typing", it's up to you which way makes the most sense. I don't have enough karma to comment, but typeof fails for boxed strings and numbers, i.e.:
alert(typeof new String('Hello World'));
alert(typeof new Number(5));
will alert "object".
Since ES2015 the correct way to check if a variable
holds a valid number is Number.isFinite(value)
Examples:
Number.isFinite(Infinity) // false
Number.isFinite(NaN) // false
Number.isFinite(-Infinity) // false
Number.isFinite(0) // true
Number.isFinite(2e64) // true
Number.isFinite('0') // false
Number.isFinite(null) // false
You're looking for isNaN():
console.log(!isNaN(123));
console.log(!isNaN(-1.23));
console.log(!isNaN(5-2));
console.log(!isNaN(0));
console.log(!isNaN("0"));
console.log(!isNaN("2"));
console.log(!isNaN("Hello"));
console.log(!isNaN("2005/12/12"));
See JavaScript isNaN() Function at MDN.
Check if the value is a string literal or String object:
function isString(o) {
return typeof o == "string" || (typeof o == "object" && o.constructor === String);
}
Unit test:
function assertTrue(value, message) {
if (!value) {
alert("Assertion error: " + message);
}
}
function assertFalse(value, message)
{
assertTrue(!value, message);
}
assertTrue(isString("string literal"), "number literal");
assertTrue(isString(new String("String object")), "String object");
assertFalse(isString(1), "number literal");
assertFalse(isString(true), "boolean literal");
assertFalse(isString({}), "object");
Checking for a number is similar:
function isNumber(o) {
return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
}
Try this,
<script>
var regInteger = /^-?\d+$/;
function isInteger( str ) {
return regInteger.test( str );
}
if(isInteger("1a11")) {
console.log( 'Integer' );
} else {
console.log( 'Non Integer' );
}
</script>
Best way to do this:
function isNumber(num) {
return (typeof num == 'string' || typeof num == 'number') && !isNaN(num - 0) && num !== '';
};
This satisfies the following test cases:
assertEquals("ISNUMBER-True: 0", true, isNumber(0));
assertEquals("ISNUMBER-True: 1", true, isNumber(-1));
assertEquals("ISNUMBER-True: 2", true, isNumber(-500));
assertEquals("ISNUMBER-True: 3", true, isNumber(15000));
assertEquals("ISNUMBER-True: 4", true, isNumber(0.35));
assertEquals("ISNUMBER-True: 5", true, isNumber(-10.35));
assertEquals("ISNUMBER-True: 6", true, isNumber(2.534e25));
assertEquals("ISNUMBER-True: 7", true, isNumber('2.534e25'));
assertEquals("ISNUMBER-True: 8", true, isNumber('52334'));
assertEquals("ISNUMBER-True: 9", true, isNumber('-234'));
assertEquals("ISNUMBER-False: 0", false, isNumber(NaN));
assertEquals("ISNUMBER-False: 1", false, isNumber({}));
assertEquals("ISNUMBER-False: 2", false, isNumber([]));
assertEquals("ISNUMBER-False: 3", false, isNumber(''));
assertEquals("ISNUMBER-False: 4", false, isNumber('one'));
assertEquals("ISNUMBER-False: 5", false, isNumber(true));
assertEquals("ISNUMBER-False: 6", false, isNumber(false));
assertEquals("ISNUMBER-False: 7", false, isNumber());
assertEquals("ISNUMBER-False: 8", false, isNumber(undefined));
assertEquals("ISNUMBER-False: 9", false, isNumber(null));
//testing data types accurately in JavaScript (opposed to "typeof")
//from http://bonsaiden.github.com/JavaScript-Garden/
function is(type, obj) {
var clas = Object.prototype.toString.call(obj).slice(8, -1);
return obj !== undefined && obj !== null && clas === type;
}
//basic usage
is('String', 'test'); // true
is('Array', true); // false
Or adapt it to return an unknown type:
function realTypeOf(obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
//usage
realTypeOf(999); // 'Number'
May 12, 2012 Update:
Full example at Javascript: A Better typeof.
Simple and thorough:
function isNumber(x) {
return parseFloat(x) == x
};
Test cases:
console.log('***TRUE CASES***');
console.log(isNumber(0));
console.log(isNumber(-1));
console.log(isNumber(-500));
console.log(isNumber(15000));
console.log(isNumber(0.35));
console.log(isNumber(-10.35));
console.log(isNumber(2.534e25));
console.log(isNumber('2.534e25'));
console.log(isNumber('52334'));
console.log(isNumber('-234'));
console.log(isNumber(Infinity));
console.log(isNumber(-Infinity));
console.log(isNumber('Infinity'));
console.log(isNumber('-Infinity'));
console.log('***FALSE CASES***');
console.log(isNumber(NaN));
console.log(isNumber({}));
console.log(isNumber([]));
console.log(isNumber(''));
console.log(isNumber('one'));
console.log(isNumber(true));
console.log(isNumber(false));
console.log(isNumber());
console.log(isNumber(undefined));
console.log(isNumber(null));
console.log(isNumber('-234aa'));
Here's an approach based on the idea of coercing the input to a number or string by adding zero or the null string, and then do a typed equality comparison.
function is_number(x) { return x === x+0; }
function is_string(x) { return x === x+""; }
For some unfathomable reason, x===x+0 seems to perform better than x===+x.
Are there any cases where this fails?
In the same vein:
function is_boolean(x) { return x === !!x; }
This appears to be mildly faster than either x===true || x===false or typeof x==="boolean" (and much faster than x===Boolean(x)).
Then there's also
function is_regexp(x) { return x === RegExp(x); }
All these depend on the existence of an "identity" operation particular to each type which can be applied to any value and reliably produce a value of the type in question. I cannot think of such an operation for dates.
For NaN, there is
function is_nan(x) { return x !== x;}
This is basically underscore's version, and as it stands is about four times faster than isNaN(), but the comments in the underscore source mention that "NaN is the only number that does not equal itself" and adds a check for _.isNumber. Why? What other objects would not equal themselves? Also, underscore uses x !== +x--but what difference could the + here make?
Then for the paranoid:
function is_undefined(x) { return x===[][0]; }
or this
function is_undefined(x) { return x===void(0); }
Or just use the invert of isNaN():
if(!isNaN(data))
do something with the number
else
it is a string
And yes, using jQuery's $.isNumeric() is more fun for the buck.
Can you just divide it by 1?
I assume the issue would be a string input like: "123ABG"
var Check = "123ABG"
if(Check == Check / 1)
{
alert("This IS a number \n")
}
else
{
alert("This is NOT a number \n")
}
Just a way I did it recently.
I think converting the var to a string decreases the performance, at least this test performed in the latest browsers shows so.
So if you care about performance, I would, I'd use this:
typeof str === "string" || str instanceof String
for checking if the variable is a string (even if you use var str = new String("foo"), str instanceof String would return true).
As for checking if it's a number I would go for the native: isNaN; function.
uh, how about just:
function IsString(obj) {
return obj !== undefined && obj != null && obj.toLowerCase !== undefined;
}
After further review many months later, this only guarantees obj is an object that has the method or property name toLowerCase defined. I am ashamed of my answer. Please see top-voted typeof one.
Beware that typeof NaN is... 'number'
typeof NaN === 'number'; // true
jQuery uses this:
function isNumber(obj) {
return !isNaN( parseFloat( obj ) ) && isFinite( obj );
}
This solution resolves many of the issues raised here!
This is by far the most reliable method I have used by far. I did not invent this, and cannot recall where I originally found it. But it works where other techniques fail:
// Begin public utility /getVarType/
// Returns 'Function', 'Object', 'Array',
// 'String', 'Number', 'Boolean', or 'Undefined'
getVarType = function ( data ){
if (undefined === data ){ return 'Undefined'; }
if (data === null ){ return 'Null'; }
return {}.toString.call(data).slice(8, -1);
};
// End public utility /getVarType/
Example of correctness
var str = new String();
console.warn( getVarType(str) ); // Reports "String"
console.warn( typeof str ); // Reports "object"
var num = new Number();
console.warn( getVarType(num) ); // Reports "Number"
console.warn( typeof num ); // Reports "object"
var list = [];
console.warn( getVarType( list ) ); // Reports "Array"
console.warn( typeof list ); // Reports "object"
Jsut an FYI, if you're using jQuery you have
$.isNumeric()
to handle this. More details on http://api.jquery.com/jQuery.isNumeric/
the best way i found which also thinks of positive and negative numbers is from :
O'Reilly Javascript and DHTML Cookbook :
function isNumber(elem) {
var str = elem.value;
var oneDecimal = false;
var oneChar = 0;
// make sure value hasn't cast to a number data type
str = str.toString( );
for (var i = 0; i < str.length; i++) {
oneChar = str.charAt(i).charCodeAt(0);
// OK for minus sign as first character
if (oneChar = = 45) {
if (i = = 0) {
continue;
} else {
alert("Only the first character may be a minus sign.");
return false;
}
}
// OK for one decimal point
if (oneChar = = 46) {
if (!oneDecimal) {
oneDecimal = true;
continue;
} else {
alert("Only one decimal is allowed in a number.");
return false;
}
}
// characters outside of 0 through 9 not OK
if (oneChar < 48 || oneChar > 57) {
alert("Enter only numbers into the field.");
return false;
}
}
return true;
}
Errr? Just use regular expressions! :)
function isInteger(val) {
return val.match(/^[0-9]$/)
}
function isFloat(val) {
return val.match(/^[0-9]*/\.[0-9]+$/)
}
since a string as '1234' with typeof will show 'string', and the inverse cannot ever happen (typeof 123 will always be number), the best is to use a simple regex /^\-?\d+$/.test(var). Or a more advanced to match floats, integers and negative numbers, /^[\-\+]?[\d]+\.?(\d+)?$/
The important side of .test is that it WON'T throw an exception if the var isn't an string, the value can be anything.
var val, regex = /^[\-\+]?[\d]+\.?(\d+)?$/;
regex.test(val) // false
val = '1234';
regex.test(val) // true
val = '-213';
regex.test(val) // true
val = '-213.2312';
regex.test(val) // true
val = '+213.2312';
regex.test(val) // true
val = 123;
regex.test(val) // true
val = new Number(123);
regex.test(val) // true
val = new String('123');
regex.test(val) // true
val = '1234e';
regex.test(val) // false
val = {};
regex.test(val) // false
val = false;
regex.test(val) // false
regex.test(undefined) // false
regex.test(null) // false
regex.test(window) // false
regex.test(document) // false
If you are looking for the real type, then typeof alone will do.
#BitOfUniverse's answer is good, and I come up with a new way:
function isNum(n) {
return !isNaN(n/0);
}
isNum('') // false
isNum(2) // true
isNum('2k') // false
isNum('2') //true
I know 0 can't be dividend, but here the function works perfectly.
typeof works very well for me in most case. You can try using an if statement
if(typeof x === 'string' || typeof x === 'number') {
console.log("Your statement");
}
where x is any variable name of your choice
Type checking
You can check the type of variable by using typeof operator:
typeof variable
Value checking
The code below returns true for numbers and false for anything else:
!isNaN(+variable);
XOR operation can be used to detect number or string.
number ^ 0 will always give the same number as output and string ^ 0 will give 0 as output.
Example:
1) 2 ^ 0 = 2
2) '2' ^ 0 = 2
3) 'Str' ^ 0 = 0
function IsNumeric(num) {
return ((num >=0 || num < 0)&& (parseInt(num)==num) );
}
For detecting numbers, the following passage from JavaScript: The Good Parts by Douglas Crockford is relevant:
The isFinite function is the best way of determining whether a value can be used as a number because it rejects NaN and Infinity . Unfortunately, isFinite will attempt to convert its operand to a number, so it is not a good test if a value is not actually a number. You may want to define your own isNumber function:
var isNumber = function isNumber(value) { return typeof value === 'number' &&
isFinite(value);
};
Simply use
myVar.constructor == String
or
myVar.constructor == Number
if you want to handle strings defined as objects or literals and saves you don't want to use a helper function.
Very late to the party; however, the following has always worked well for me when I want to check whether some input is either a string or a number in one shot.
return !!Object.prototype.toString.call(input).match(/\[object (String|Number)\]/);

Check If Input Is a Number, Turn Input Into String With JavaScript [duplicate]

Does anyone know how can I check whether a variable is a number or a string in JavaScript?
If you're dealing with literal notation, and not constructors, you can use typeof:.
typeof "Hello World"; // string
typeof 123; // number
If you're creating numbers and strings via a constructor, such as var foo = new String("foo"), you should keep in mind that typeof may return object for foo.
Perhaps a more foolproof method of checking the type would be to utilize the method found in underscore.js (annotated source can be found here),
var toString = Object.prototype.toString;
_.isString = function (obj) {
return toString.call(obj) == '[object String]';
}
This returns a boolean true for the following:
_.isString("Jonathan"); // true
_.isString(new String("Jonathan")); // true
Best way to do that is using isNaN + type casting:
Updated all-in method:
function isNumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) }
The same using regex:
function isNumber(n) { return /^-?[\d.]+(?:e-?\d+)?$/.test(n); }
------------------------
isNumber('123'); // true
isNumber('123abc'); // false
isNumber(5); // true
isNumber('q345'); // false
isNumber(null); // false
isNumber(undefined); // false
isNumber(false); // false
isNumber(' '); // false
The best way I have found is to either check for a method on the string, i.e.:
if (x.substring) {
// do string thing
} else{
// do other thing
}
or if you want to do something with the number check for a number property,
if (x.toFixed) {
// do number thing
} else {
// do other thing
}
This is sort of like "duck typing", it's up to you which way makes the most sense. I don't have enough karma to comment, but typeof fails for boxed strings and numbers, i.e.:
alert(typeof new String('Hello World'));
alert(typeof new Number(5));
will alert "object".
Since ES2015 the correct way to check if a variable
holds a valid number is Number.isFinite(value)
Examples:
Number.isFinite(Infinity) // false
Number.isFinite(NaN) // false
Number.isFinite(-Infinity) // false
Number.isFinite(0) // true
Number.isFinite(2e64) // true
Number.isFinite('0') // false
Number.isFinite(null) // false
You're looking for isNaN():
console.log(!isNaN(123));
console.log(!isNaN(-1.23));
console.log(!isNaN(5-2));
console.log(!isNaN(0));
console.log(!isNaN("0"));
console.log(!isNaN("2"));
console.log(!isNaN("Hello"));
console.log(!isNaN("2005/12/12"));
See JavaScript isNaN() Function at MDN.
Check if the value is a string literal or String object:
function isString(o) {
return typeof o == "string" || (typeof o == "object" && o.constructor === String);
}
Unit test:
function assertTrue(value, message) {
if (!value) {
alert("Assertion error: " + message);
}
}
function assertFalse(value, message)
{
assertTrue(!value, message);
}
assertTrue(isString("string literal"), "number literal");
assertTrue(isString(new String("String object")), "String object");
assertFalse(isString(1), "number literal");
assertFalse(isString(true), "boolean literal");
assertFalse(isString({}), "object");
Checking for a number is similar:
function isNumber(o) {
return typeof o == "number" || (typeof o == "object" && o.constructor === Number);
}
Try this,
<script>
var regInteger = /^-?\d+$/;
function isInteger( str ) {
return regInteger.test( str );
}
if(isInteger("1a11")) {
console.log( 'Integer' );
} else {
console.log( 'Non Integer' );
}
</script>
Best way to do this:
function isNumber(num) {
return (typeof num == 'string' || typeof num == 'number') && !isNaN(num - 0) && num !== '';
};
This satisfies the following test cases:
assertEquals("ISNUMBER-True: 0", true, isNumber(0));
assertEquals("ISNUMBER-True: 1", true, isNumber(-1));
assertEquals("ISNUMBER-True: 2", true, isNumber(-500));
assertEquals("ISNUMBER-True: 3", true, isNumber(15000));
assertEquals("ISNUMBER-True: 4", true, isNumber(0.35));
assertEquals("ISNUMBER-True: 5", true, isNumber(-10.35));
assertEquals("ISNUMBER-True: 6", true, isNumber(2.534e25));
assertEquals("ISNUMBER-True: 7", true, isNumber('2.534e25'));
assertEquals("ISNUMBER-True: 8", true, isNumber('52334'));
assertEquals("ISNUMBER-True: 9", true, isNumber('-234'));
assertEquals("ISNUMBER-False: 0", false, isNumber(NaN));
assertEquals("ISNUMBER-False: 1", false, isNumber({}));
assertEquals("ISNUMBER-False: 2", false, isNumber([]));
assertEquals("ISNUMBER-False: 3", false, isNumber(''));
assertEquals("ISNUMBER-False: 4", false, isNumber('one'));
assertEquals("ISNUMBER-False: 5", false, isNumber(true));
assertEquals("ISNUMBER-False: 6", false, isNumber(false));
assertEquals("ISNUMBER-False: 7", false, isNumber());
assertEquals("ISNUMBER-False: 8", false, isNumber(undefined));
assertEquals("ISNUMBER-False: 9", false, isNumber(null));
//testing data types accurately in JavaScript (opposed to "typeof")
//from http://bonsaiden.github.com/JavaScript-Garden/
function is(type, obj) {
var clas = Object.prototype.toString.call(obj).slice(8, -1);
return obj !== undefined && obj !== null && clas === type;
}
//basic usage
is('String', 'test'); // true
is('Array', true); // false
Or adapt it to return an unknown type:
function realTypeOf(obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
//usage
realTypeOf(999); // 'Number'
May 12, 2012 Update:
Full example at Javascript: A Better typeof.
Simple and thorough:
function isNumber(x) {
return parseFloat(x) == x
};
Test cases:
console.log('***TRUE CASES***');
console.log(isNumber(0));
console.log(isNumber(-1));
console.log(isNumber(-500));
console.log(isNumber(15000));
console.log(isNumber(0.35));
console.log(isNumber(-10.35));
console.log(isNumber(2.534e25));
console.log(isNumber('2.534e25'));
console.log(isNumber('52334'));
console.log(isNumber('-234'));
console.log(isNumber(Infinity));
console.log(isNumber(-Infinity));
console.log(isNumber('Infinity'));
console.log(isNumber('-Infinity'));
console.log('***FALSE CASES***');
console.log(isNumber(NaN));
console.log(isNumber({}));
console.log(isNumber([]));
console.log(isNumber(''));
console.log(isNumber('one'));
console.log(isNumber(true));
console.log(isNumber(false));
console.log(isNumber());
console.log(isNumber(undefined));
console.log(isNumber(null));
console.log(isNumber('-234aa'));
Here's an approach based on the idea of coercing the input to a number or string by adding zero or the null string, and then do a typed equality comparison.
function is_number(x) { return x === x+0; }
function is_string(x) { return x === x+""; }
For some unfathomable reason, x===x+0 seems to perform better than x===+x.
Are there any cases where this fails?
In the same vein:
function is_boolean(x) { return x === !!x; }
This appears to be mildly faster than either x===true || x===false or typeof x==="boolean" (and much faster than x===Boolean(x)).
Then there's also
function is_regexp(x) { return x === RegExp(x); }
All these depend on the existence of an "identity" operation particular to each type which can be applied to any value and reliably produce a value of the type in question. I cannot think of such an operation for dates.
For NaN, there is
function is_nan(x) { return x !== x;}
This is basically underscore's version, and as it stands is about four times faster than isNaN(), but the comments in the underscore source mention that "NaN is the only number that does not equal itself" and adds a check for _.isNumber. Why? What other objects would not equal themselves? Also, underscore uses x !== +x--but what difference could the + here make?
Then for the paranoid:
function is_undefined(x) { return x===[][0]; }
or this
function is_undefined(x) { return x===void(0); }
Or just use the invert of isNaN():
if(!isNaN(data))
do something with the number
else
it is a string
And yes, using jQuery's $.isNumeric() is more fun for the buck.
Can you just divide it by 1?
I assume the issue would be a string input like: "123ABG"
var Check = "123ABG"
if(Check == Check / 1)
{
alert("This IS a number \n")
}
else
{
alert("This is NOT a number \n")
}
Just a way I did it recently.
I think converting the var to a string decreases the performance, at least this test performed in the latest browsers shows so.
So if you care about performance, I would, I'd use this:
typeof str === "string" || str instanceof String
for checking if the variable is a string (even if you use var str = new String("foo"), str instanceof String would return true).
As for checking if it's a number I would go for the native: isNaN; function.
uh, how about just:
function IsString(obj) {
return obj !== undefined && obj != null && obj.toLowerCase !== undefined;
}
After further review many months later, this only guarantees obj is an object that has the method or property name toLowerCase defined. I am ashamed of my answer. Please see top-voted typeof one.
Beware that typeof NaN is... 'number'
typeof NaN === 'number'; // true
jQuery uses this:
function isNumber(obj) {
return !isNaN( parseFloat( obj ) ) && isFinite( obj );
}
This solution resolves many of the issues raised here!
This is by far the most reliable method I have used by far. I did not invent this, and cannot recall where I originally found it. But it works where other techniques fail:
// Begin public utility /getVarType/
// Returns 'Function', 'Object', 'Array',
// 'String', 'Number', 'Boolean', or 'Undefined'
getVarType = function ( data ){
if (undefined === data ){ return 'Undefined'; }
if (data === null ){ return 'Null'; }
return {}.toString.call(data).slice(8, -1);
};
// End public utility /getVarType/
Example of correctness
var str = new String();
console.warn( getVarType(str) ); // Reports "String"
console.warn( typeof str ); // Reports "object"
var num = new Number();
console.warn( getVarType(num) ); // Reports "Number"
console.warn( typeof num ); // Reports "object"
var list = [];
console.warn( getVarType( list ) ); // Reports "Array"
console.warn( typeof list ); // Reports "object"
Jsut an FYI, if you're using jQuery you have
$.isNumeric()
to handle this. More details on http://api.jquery.com/jQuery.isNumeric/
the best way i found which also thinks of positive and negative numbers is from :
O'Reilly Javascript and DHTML Cookbook :
function isNumber(elem) {
var str = elem.value;
var oneDecimal = false;
var oneChar = 0;
// make sure value hasn't cast to a number data type
str = str.toString( );
for (var i = 0; i < str.length; i++) {
oneChar = str.charAt(i).charCodeAt(0);
// OK for minus sign as first character
if (oneChar = = 45) {
if (i = = 0) {
continue;
} else {
alert("Only the first character may be a minus sign.");
return false;
}
}
// OK for one decimal point
if (oneChar = = 46) {
if (!oneDecimal) {
oneDecimal = true;
continue;
} else {
alert("Only one decimal is allowed in a number.");
return false;
}
}
// characters outside of 0 through 9 not OK
if (oneChar < 48 || oneChar > 57) {
alert("Enter only numbers into the field.");
return false;
}
}
return true;
}
Errr? Just use regular expressions! :)
function isInteger(val) {
return val.match(/^[0-9]$/)
}
function isFloat(val) {
return val.match(/^[0-9]*/\.[0-9]+$/)
}
since a string as '1234' with typeof will show 'string', and the inverse cannot ever happen (typeof 123 will always be number), the best is to use a simple regex /^\-?\d+$/.test(var). Or a more advanced to match floats, integers and negative numbers, /^[\-\+]?[\d]+\.?(\d+)?$/
The important side of .test is that it WON'T throw an exception if the var isn't an string, the value can be anything.
var val, regex = /^[\-\+]?[\d]+\.?(\d+)?$/;
regex.test(val) // false
val = '1234';
regex.test(val) // true
val = '-213';
regex.test(val) // true
val = '-213.2312';
regex.test(val) // true
val = '+213.2312';
regex.test(val) // true
val = 123;
regex.test(val) // true
val = new Number(123);
regex.test(val) // true
val = new String('123');
regex.test(val) // true
val = '1234e';
regex.test(val) // false
val = {};
regex.test(val) // false
val = false;
regex.test(val) // false
regex.test(undefined) // false
regex.test(null) // false
regex.test(window) // false
regex.test(document) // false
If you are looking for the real type, then typeof alone will do.
#BitOfUniverse's answer is good, and I come up with a new way:
function isNum(n) {
return !isNaN(n/0);
}
isNum('') // false
isNum(2) // true
isNum('2k') // false
isNum('2') //true
I know 0 can't be dividend, but here the function works perfectly.
typeof works very well for me in most case. You can try using an if statement
if(typeof x === 'string' || typeof x === 'number') {
console.log("Your statement");
}
where x is any variable name of your choice
Type checking
You can check the type of variable by using typeof operator:
typeof variable
Value checking
The code below returns true for numbers and false for anything else:
!isNaN(+variable);
XOR operation can be used to detect number or string.
number ^ 0 will always give the same number as output and string ^ 0 will give 0 as output.
Example:
1) 2 ^ 0 = 2
2) '2' ^ 0 = 2
3) 'Str' ^ 0 = 0
function IsNumeric(num) {
return ((num >=0 || num < 0)&& (parseInt(num)==num) );
}
For detecting numbers, the following passage from JavaScript: The Good Parts by Douglas Crockford is relevant:
The isFinite function is the best way of determining whether a value can be used as a number because it rejects NaN and Infinity . Unfortunately, isFinite will attempt to convert its operand to a number, so it is not a good test if a value is not actually a number. You may want to define your own isNumber function:
var isNumber = function isNumber(value) { return typeof value === 'number' &&
isFinite(value);
};
Simply use
myVar.constructor == String
or
myVar.constructor == Number
if you want to handle strings defined as objects or literals and saves you don't want to use a helper function.
Very late to the party; however, the following has always worked well for me when I want to check whether some input is either a string or a number in one shot.
return !!Object.prototype.toString.call(input).match(/\[object (String|Number)\]/);

Recursive methods using Javascript

I'm trying to replicate the json stringify method but instead use recursion. I've been able to pass alot of test cases but when it comes to nested arrays I seem to be having issues. if there's any empty array inside an array ('[]'), i get something like [,7,9] instead of [[],7,9]. Also if I pass in:
stringifyJSON([[["test","mike",4,["jake"]],3,4]])
"[[test,mike,4,jake,3,4]]"
I thought I was close in getting this to work, but I might have to start over. Do you guys have any ideas on what I might be able to change to make this work for nested examples? Here's the code I have now:
var testarray = [9,[[],2,3]] //should return '[9,[[],2,3]]'
var count = 0
var stringifyJSON = function(obj,stack) {
var typecheck = typeof obj;
var resarray = stack;
if(resarray == null){ //does resarray exist? Is this the first time through?
var resarray = [];
}
if(typeof obj === "string"){ //Is obj a string?
return '"' + String(obj) + '"';
}
if((Array.isArray(obj)) && (obj.length > 0)){ //If not a string, is it an object?
for(var i = 0; i<obj.length;i++){
if(Array.isArray(obj[i])){
var arraytemp = []
stringifyJSON(arraytemp.push(obj[i]),resarray) // this is probably incorrect, this is how i handle a nested array situation
}
if(typeof obj[i] === 'number'){ //if the number is inside of the array, don't quote it
resarray.push(obj[i]);
}
else if(typecheck === 'object' && Array.isArray(obj[0])){
resarray.push('[' + obj[i] + ']');
}
else{
resarray.push('"' + obj[i] + '"');
}
obj.shift() //delete the first object in the array and get ready to recurse to get to the second object.
stringifyJSON(obj,resarray); //remember the new array when recursing by passing it into the next recursive instance
}
}
if(obj !== null && typeof obj === 'object'){ //is obj an object?
for(var key in obj){
stringifyJSON(resarray.push(key + '"' + ':' + obj[key]),resarray)
}
}
if(typeof obj === "number" || obj == null || obj === true || obj === false){ //special cases and if it's a number
return '' + obj + ''
}
if(typecheck === 'object'){ //a special case where you have an empty array that needs to be quoted.
return '['+resarray+']'
}
return '' + resarray.join('') + '';
};
//JSON values cannot be a function, a date, or undefined
Do you guys have any ideas on what I might be able to change to make this work for nested examples?
Sure, but it's going to scrap you entire function, so I hope you don't mind. I'll provide a bullet-list of points why this approach is essential and yours is essentially flawed from the get-go :(
Corner cases
This function does a simple case analysis on a non-null data's constructor property and encodes accordingly. It manages to cover a lot of corner cases that you're unlikely to consider, such as
JSON.stringify(undefined) returns undefined
JSON.stringify(null) returns 'null'
JSON.stringify(true) returns 'true'
JSON.stringify([1,2,undefined,4]) returns '[1,2,null,4]'
JSON.stringify({a: undefined, b: 2}) returns '{ "b": 2 }'
JSON.stringify({a: /foo/}) returns { "a": {} }
So to verify that our stringifyJSON function actually works properly, I'm not going to test the output of it directly. Instead, I'm going to write a little test method that ensures the JSON.parse of our encoded JSON actually returns our original input value
// we really only care that JSON.parse can work with our result
// the output value should match the input value
// if it doesn't, we did something wrong in our stringifier
const test = data => {
return console.log(JSON.parse(stringifyJSON(data)))
}
test([1,2,3]) // should return [1,2,3]
test({a:[1,2,3]}) // should return {a:[1,2,3]}
Disclaimer: it should be obvious that the code I'm about to share is not meant to be used as an actual replacement for JSON.stringify – there's countless corner cases we probably didn't address. Instead, this code is shared to provide a demonstration for how we could go about such a task. Additional corner cases could easily be added to this function.
Runnable demo
Without further ado, here is stringifyJSON in a runnable demo that verifies excellent compatibility for several common cases
const stringifyJSON = data => {
if (data === undefined)
return undefined
else if (data === null)
return 'null'
else if (data.constructor === String)
return '"' + data.replace(/"/g, '\\"') + '"'
else if (data.constructor === Number)
return String(data)
else if (data.constructor === Boolean)
return data ? 'true' : 'false'
else if (data.constructor === Array)
return '[ ' + data.reduce((acc, v) => {
if (v === undefined)
return [...acc, 'null']
else
return [...acc, stringifyJSON(v)]
}, []).join(', ') + ' ]'
else if (data.constructor === Object)
return '{ ' + Object.keys(data).reduce((acc, k) => {
if (data[k] === undefined)
return acc
else
return [...acc, stringifyJSON(k) + ':' + stringifyJSON(data[k])]
}, []).join(', ') + ' }'
else
return '{}'
}
// round-trip test and log to console
const test = data => {
return console.log(JSON.parse(stringifyJSON(data)))
}
test(null) // null
test('he said "hello"') // 'he said "hello"'
test(5) // 5
test([1,2,true,false]) // [ 1, 2, true, false ]
test({a:1, b:2}) // { a: 1, b: 2 }
test([{a:1},{b:2},{c:3}]) // [ { a: 1 }, { b: 2 }, { c: 3 } ]
test({a:[1,2,3], c:[4,5,6]}) // { a: [ 1, 2, 3 ], c: [ 4, 5, 6 ] }
test({a:undefined, b:2}) // { b: 2 }
test([[["test","mike",4,["jake"]],3,4]]) // [ [ [ 'test', 'mike', 4, [ 'jake' ] ], 3, 4 ] ]
"So why is this better?"
this works for more than just Array types – we can stringify Strings, Numbers, Arrays, Objects, Array of Numbers, Arrays of Objects, Objects containing Arrays of Strings, even nulls and undefineds, and so on – you get the idea
each case of our stringifyJSON object is like a little program that tells us exactly how to encode each type (eg String, Number, Array, Object etc)
no whacked out typeof type checking – after we check for the undefined and null cases, we know we can try to read the constructor property.
no manual looping where we have to mentally keep track of counter variables, how/when to increment them
no complex if conditions using &&, ||, !, or checking things like x > y.length etc
no use of obj[0] or obj[i] that stresses our brain out
no assumptions about Arrays/Objects being empty – and without having to check the length property
no other mutations for that matter – that means we don't have to think about some master return value resarray or what state it's in after push calls happen at various stages in the program
Custom objects
JSON.stringify allows us to set a toJSON property on our custom objects so that when we stringify them, we will get the result we want.
const Foo = x => ({
toJSON: () => ({ type: 'Foo', value: x })
})
console.log(JSON.stringify(Foo(5)))
// {"type":"Foo","value":5}
We could easily add this kind of functionality to our code above – changes in bold
const stringifyJSON = data => {
if (data === undefined)
return undefined
else if (data === null)
return 'null'
else if (data.toJSON instanceof Function)
return stringifyJSON(data.toJSON())
...
else
return '{}'
}
test({toJSON: () => ({a:1, b:2})}) // { a: 1, b: 2 }
So after playing around with your code, I found that if you replace:
resarray.push('[' + obj[i] + ']');
with:
resarray.push(stringifyJSON(obj[i])) it works well with the arrays and still satisfies your recursive process.
Also I found a few quirks with running it through objects like { hello: 5, arr: testarray, arr2: [1, 2,3, "hello"], num: 789, str: '4444', str2: "67494" }; and found that by changing the stringifying of objects from:
stringifyJSON(resarray.push(key + '"' + ':' + obj[key]),resarray)
to something more like:
stringifyJSON(resarray.push('"' + key + '"' + ':' + stringifyJSON(obj[key])),resarray);
it should workout more of how you want. This is really cool though and I had fun playing around with it!

Javascript, add string if true

I need to modify this function:
function checkPermissions(fid, obj) {
$("#permissions_"+fid+"_canview").attr("checked", obj.checked);
}
if the param "n" is "true" then instead of #permissions it'll output #permissionsSet.
is that possible?
OP clarified the question to be change this whether or not a 3rd parameter was provided. Here you go.
function checkPermissions(fid, obj, n) {
var id = n !== undefined ? '#permissionsSet' : '#permissions';
$(id + fid + "_canview").attr("checked", obj.checked);
}
Note: This function can be freely used with passing 2 or 3 parameters (or really any number).
checkPermissions(1, this); // Ok n === undefined
checkPermissions(1, this, true); // Ok n === true
checkPermissions(1); // Okish n and obj === undefined
function checkPermissions(fid, obj, n) {
$("#permissions" + ((n) ? "Set" : "") + "_"+fid+"_canview").attr("checked", obj.checked);
}

Determining if a Javascript object is a "complex" object or just a string

I want to be able to pass either a string literal,
'this is a string'
or a javascript object,
{one: 'this', two: 'is', three: 'a', four: 'string' }
as argument to a function, and take different actions depending on whether it's a string or an object. How do I determine which is true?
To be specific, I want to iterate over the properties of an object, and do some parsing if a property is a string, but nest recursively if the property is an object. I've figured out how to use $.each() to iterate over the properties of the object, but if I just do this with the string, it treates the string as an array of letters rather than as a single thing. Can I get around this some other way?
var data = {
foo: "I'm a string literal",
bar: {
content: "I'm within an object"
}
};
jQuery
$.each(data, function(i, element){
if($.isPlainObject(element){
// we got an object here
}
});
There are similar methods like $.isArray() or $.isFunction() within the jQuery lib.
Native Javascript
for(var element in data){
if(toString.call(element) === '[object Object]'){
// we got an object here
}
}
To use the hack'ish way with toString has the advantage, that you can identify whether it is really an object and an array. Both, objects and arrays would return object by using typeof element.
Long story short, you cannot rely on the typeof operator to distinguish true objects and arrays. For that you need the toString.call(). If you just need to know whether it is any object or not, typeof is just fine.
var a = 'this is a string';
console.log(typeof a); // Displays: "string"
var b = {one: 'this', two: 'is', three: 'a', four: 'string' };
console.log(typeof b); // Displays: "object"
Therefore:
if (typeof yourArgument === 'string') {
// Do the string parsing
}
else if (typeof yourArgument === 'object') {
// Do the property enumeration
}
else {
// Throw exception
}
UPDATE:
Some further considerations:
See #Andy E's comment below.
typeof null returns "object" as well. The same applies to any other object, including arrays.
Try this:
function some_function(argument) {
if (typeof(argument) == "string" || argument.constructor == String) {
// it's a string literal
} else if (argument && typeof(argument) == "object" && argument.constructor != Array) {
// it's an object and not null
} else {
// error
}
}
Thanks to Andy E for the tipp with argument.constructor.
Try the typeof operator. It will return object for objects and string for strings.
you can do something like this
function something(variableX){
if (typeof(variableX) === 'object'){
// Do something
}else if (typeof(variableX) === 'string'){
// Do something
}
}
I was having a similar problem and I think I figured out a solution. Here is my sample code for anyone who is interested.
var propToDotSyntax = function (obj) {
var parse = function (o, n) {
var a = [], t;
for (var p in o) {
if (o.hasOwnProperty(p)) {
t = o[p];
if (n !== undefined) tmp = n + '.' + p;
else tmp = p;
if (t && typeof(t) === 'object') a.push(arguments.callee(t, tmp));
else a.push(tmp + '=' + t);
}
}
return a;
};
return parse(obj).toString();
}
var i = { prop: 'string', obj: { subprop: 'substring', subobj: { subsubprop: 'subsubstring' } } };
propToDotSyntax(i);
This will go through all the properties of an object — even if the properties are objects themselves — and return a string with the following values in dot syntax.
"prop=string,obj.subprop=substring,obj.subobj.subsubprop=subsubstring"
I got the inspiration from DavidPirek.com — Thanks Mr. Pirek!

Categories

Resources