JavaScript gettype
Returns the type of the variable
1 2 3 4 56 7 8 9 1011 12 13 14 1516 17 18 19 2021 22 23 24 2526 27 28 29 3031 32 33 34 3536 37 38 39 4041 42 43 44 4546 47 48 49 5051 52 53 54 5556 57 58 59 | function gettype (mixed_var) { // Returns the type of the variable // // version: 1008.1718 // discuss at: http://phpjs.org/functions/gettype // + original by: Paulo Freitas // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) // + improved by: Douglas Crockford (http://javascript.crockford.com) // + input by: KELAN // + improved by: Brett Zamir (http://brett-zamir.me) // - depends on: is_float // % note 1: 1.0 is simplified to 1 before it can be accessed by the function, this makes // % note 1: it different from the PHP implementation. We can't fix this unfortunately. // * example 1: gettype(1); // * returns 1: 'integer' // * example 2: gettype(undefined); // * returns 2: 'undefined' // * example 3: gettype({0: 'Kevin van Zonneveld'}); // * returns 3: 'array' // * example 4: gettype('foo'); // * returns 4: 'string' // * example 5: gettype({0: function () {return false;}}); // * returns 5: 'array' var s = typeof mixed_var, name; var getFuncName = function (fn) { var name = (/\W*function\s+([\w\$]+)\s*\(/).exec(fn); if (!name) { return '(Anonymous)'; } return name[1]; }; if (s === 'object') { if (mixed_var !== null) { // From: http://javascript.crockford.com/remedial.html if (typeof mixed_var.length === 'number' && !(mixed_var.propertyIsEnumerable('length')) && typeof mixed_var.splice === 'function') { s = 'array'; } else if (mixed_var.constructor && getFuncName(mixed_var.constructor)) { name = getFuncName(mixed_var.constructor); if (name === 'Date') { s = 'date'; // not in PHP } else if (name === 'RegExp') { s = 'regexp'; // not in PHP } else if (name === 'PHPJS_Resource') { // Check against our own resource constructor s = 'resource'; } } } else { s = 'null'; } } else if (s === 'number') { s = this.is_float(mixed_var) ? 'double' : 'integer'; } return s; } |
Examples
» Example 1
Running
1 | gettype(1); |
Should return
1 | 'integer' |
» Example 2
Running
1 | gettype(undefined); |
Should return
1 | 'undefined' |
Dependencies
In order to use this function, you also need:
Open syntax issues
php.js uses JsLint to help us keep our code consistent and prevent some common bugs.
Eventually we want all code to pass or at least take into consideration most fixes suggested by JsLint, following this JsLint configuration we’ve decided on.
Authors
Thanks to the following developers, you get to have gettype goodness in JavaScript.
@ KELAN: I noticed your version relies on toString. This raises a question for me. What if people supply objects that actually return some custom string?
function gettype(mixed_var){
switch (Object.prototype.toString.apply(mixed_var)){
case '[object Array]' : return 'array';
case '[object Function]': return 'function';
case '[object String]' : return 'string';
case '[object RegExp]' : return 'regexp';
case '[object Boolean]' : return 'boolean';
case '[object Date]' : return 'date';
case '[object Math]' : return 'math';
case '[object Number]' : {
if (parseFloat(mixed_var) != parseInt(mixed_var)) return 'double';
else return 'integer';
}
case '[object Object]' : {
if(mixed_var===undefined)return 'undefined';
else if(mixed_var==null)return 'NULL';
else return 'object';
}
default : return 'unknown type';
}
}
Yes, this function won't work unless you pass the variable as a string (and then only if the variable is in a global context). There's no other way to change the type of the variable by reference like that, so that was the only way we can mimic the PHP behavior here.
[CODE="Javascript"]
$foo = "5bar"; // string
$bar = true; // boolean
settype('$foo', "integer"); // $foo is now 5 (integer)
alert(typeof $foo); // number
settype('$bar', "string"); // $bar is now "1" (string)
alert(typeof $bar); // string
[/CODE]
@ Brett Zamir & Onno Marsman: Can't submit yet, but actually made some progress with the UI today:
http://phpjs.org/packages/configure
You can play around with the get_html_translation_table, html_entity_decode, htmlentities, htmlspecialchars, htmlspecialchars_decode a bit to get the idea.
I personally would like to focus my time a bit more towards the site for now. Brett, is it an idea we get you SVN access? We don't always agree on implementations but I'm sure by now you have a solid understanding beforehand of what functions are controversial in the eyes of Onno & myself. We could always talk about it then.
This way you can directly patch/add your functions, and I can use my IDE primarily for phpjs.org for the time being. If not: no problem at all, Just let me know ok? Might as well pimp you to core member if you're interested (in fact there's no real difference, just the name) :)
@ Brett Zamir: For some reason when it reaches case 'integer', I can't set the this[vr] to anything anymore. Strange, because the other (var bar) example does work.
And by the way, I believe congratulations are in order Brett:
http://phpjs.org/authors/index :)
I'm going to do some work on the site now, Pedro Sland has supplied a jquery component to the compiler I'm anxious to wire up.
@ Brett Zamir: Processed everything: still having a bit of a problem with the first testcase. It continues to return 5bar but I will look into it.
The regular expression line under 'float' should be changed to this:
var mtch = v.match(/^([+-]?)(\d+(\.\d+)?|\.\d+)([eE][+-]?\d+)?/);
(Had forgotten the +/- after exponent...)
By the way, you can get doubleval() by returning floatval() on it, and get is_double() by returning is_float().
I think you should change get_resource_type() and is_resource() to not porting (unless you just want to return false for the latter!), since JavaScript doesn't have the resource type.
Here's settype() following PHP behavior
[CODE="Javascript"]// Credits to Crockford also
// only works on global variables, and "vr" must be passed in as a string
function settype (vr, type) {
function is_array(arr) {
return typeof arr === 'object' && typeof arr.length === 'number' &&
!(arr.propertyIsEnumerable('length')) &&
typeof arr.splice === 'function'
}
v = this[vr];
try {
switch(type) {
case 'boolean':
if (is_array(v) && v.length === 0) {this[vr]=false;}
else if (v === '0') {this[vr]=false;}
else if (typeof v === 'object' && !is_array(v)) {
var lgth = false;
for (var i in v) {
lgth = true;
}
this[vr]=lgth;
}
else {this[vr] = !!v;}
break;
case 'integer':
if (typeof v === 'number') {this[vr]=parseInt(v, 10);}
else if (typeof v === 'string') {
var mtch = v.match(/^([+-]?)(\d+)/);
if (!mtch) {this[vr]=0;}
else {this[vr]=parseInt(v, 10);}
}
else if (v === true) {this[vr]=1;}
else if (v === false || v === null) {this[vr]=0;}
else if (is_array(v) && v.length === 0) {this[vr]=0;}
else if (typeof v === 'object') {this[vr]=1;}
break;
case 'float':
if (typeof v === 'string') {
var mtch = v.match(/^([+-]?)(\d+(\.\d+)?|\.\d+)([eE]\d+)?/);
if (!mtch) {this[vr]=0;}
else {this[vr]=parseFloat(v, 10);}
}
else if (v === true) {this[vr]=1;}
else if (v === false || v === null) {this[vr]=0;}
else if (is_array(v) && v.length === 0) {this[vr]=0;}
else if (typeof v === 'object') {this[vr]=1;}
break;
case 'string':
if (v === null || v === false) {this[vr]='';}
else if (is_array(v)) {this[vr]='Array';}
else if (typeof v === 'object') {this[vr]='Object';}
else if (v === true) {this[vr]='1';}
else {this[vr] += '';} // numbers (and functions?)
break;
case 'array':
if (v === null) {this[vr] = [];}
else if (typeof v !== 'object') {this[vr] = [v];}
break;
case 'object':
if (v === null) {this[vr]={};}
else if (is_array(v)) {
for (var i=0, obj={}; i < v.length; i++) {
obj[i] = v;
}
this[vr] = obj;
}
else if (typeof v !== 'object') {this[vr]={scalar:v};}
break;
case 'null':
delete this[vr];
break;
}
return true;
}
catch (e) {
return false;
}
}
var a =5;
settype('a', 'object');
alert(typeof a);[/CODE]
Unless you really want to check the javascript type. I guess functions that check for the type array really do this to make a distinction between associative array like objects and real javascript arrays. So I don't really think there is a problem...


Brett Zamir
30 Apr '09