Encontrar tipo de variable en JavaScript

146

En Java, puede usar instanceOfo getClass()en una variable para averiguar su tipo.

¿Cómo descubro el tipo de variable en JavaScript que no está fuertemente tipado?

Por ejemplo, ¿cómo sé si bares a Booleano a Number, o a String?

function foo(bar) {
    // what do I do here?
}
Tom Tucker
fuente
ver también: stackoverflow.com/questions/24318654
dreftymac

Respuestas:

242

Uso typeof:

> typeof "foo"
"string"
> typeof true
"boolean"
> typeof 42
"number"

Entonces puedes hacer:

if(typeof bar === 'number') {
   //whatever
}

Sin embargo, tenga cuidado si define estas primitivas con sus envoltorios de objetos (que nunca debe hacer, use literales siempre que sea posible):

> typeof new Boolean(false)
"object"
> typeof new String("foo")
"object"
> typeof new Number(42)
"object"

El tipo de una matriz es todavía object. Aquí realmente necesitas el instanceofoperador.

Actualizar:

Otra forma interesante es examinar la salida de Object.prototype.toString:

> Object.prototype.toString.call([1,2,3])
"[object Array]"
> Object.prototype.toString.call("foo bar")
"[object String]"
> Object.prototype.toString.call(45)
"[object Number]"
> Object.prototype.toString.call(false)
"[object Boolean]"
> Object.prototype.toString.call(new String("foo bar"))
"[object String]"
> Object.prototype.toString.call(null)
"[object Null]"
> Object.prototype.toString.call(/123/)
"[object RegExp]"
> Object.prototype.toString.call(undefined)
"[object Undefined]"

Con eso no tendrías que distinguir entre valores primitivos y objetos.

Felix Kling
fuente
¿Cuál sería el inconveniente de usar proto .constructor.name? Una función siple sería: function getVariableType (object) {return (object .__ proto__.constructor.name); }
Stu
actualizar a la definición de función que mencioné anteriormente: function getVariableType (object) {return (object === undefined? "Undefined": object.__proto__.constructor.name);
Stu
29

typeof solo es bueno para devolver los tipos "primitivos" como número, booleano, objeto, cadena y símbolos. También puede usar instanceofpara probar si un objeto es de un tipo específico.

function MyObj(prop) {
  this.prop = prop;
}

var obj = new MyObj(10);

console.log(obj instanceof MyObj && obj instanceof Object); // outputs true
Juan mendes
fuente
23

Utilizando type:

// Numbers
typeof 37                === 'number';
typeof 3.14              === 'number';
typeof Math.LN2          === 'number';
typeof Infinity          === 'number';
typeof NaN               === 'number'; // Despite being "Not-A-Number"
typeof Number(1)         === 'number'; // but never use this form!

// Strings
typeof ""                === 'string';
typeof "bla"             === 'string';
typeof (typeof 1)        === 'string'; // typeof always return a string
typeof String("abc")     === 'string'; // but never use this form!

// Booleans
typeof true              === 'boolean';
typeof false             === 'boolean';
typeof Boolean(true)     === 'boolean'; // but never use this form!

// Undefined
typeof undefined         === 'undefined';
typeof blabla            === 'undefined'; // an undefined variable

// Objects
typeof {a:1}             === 'object';
typeof [1, 2, 4]         === 'object'; // use Array.isArray or Object.prototype.toString.call to differentiate regular objects from arrays
typeof new Date()        === 'object';
typeof new Boolean(true) === 'object'; // this is confusing. Don't use!
typeof new Number(1)     === 'object'; // this is confusing. Don't use!
typeof new String("abc") === 'object';  // this is confusing. Don't use!

// Functions
typeof function(){}      === 'function';
typeof Math.sin          === 'function';
Krishna Singh
fuente
No hay problemas con el uso. Number(1), Boolean(true)...Los únicos problemas son cuando se usa newy se crea un objeto en caja, usarlos como funciones puede ser realmente útil para la conversión de otros tipos. Boolean(0) === false, Number(true) === 1
Juan Mendes
¿qué pasa null? typeof nulles 'objeto'
Dheeraj
15

En Javascript puedes hacerlo usando la función typeof

function foo(bar){
  alert(typeof(bar));
}
wajiw
fuente
3
Como mencioné en mi respuesta, typof solo devolverá número, booleano, objeto, cadena. No es útil para determinar otros tipos, como Array, RegExp o tipos personalizados.
Juan Mendes
7

Para ser un poco más preciso con ECMAScript-5.1 que las otras respuestas (algunos podrían decir pedante):

En JavaScript, las variables (y propiedades) no tienen tipos: los valores sí. Además, solo hay 6 tipos de valores: Indefinido, Nulo, Booleano, Cadena, Número y Objeto. (Técnicamente, también hay 7 "tipos de especificación", pero no puede almacenar valores de esos tipos como propiedades de objetos o valores de variables; solo se usan dentro de la propia especificación, para definir cómo funciona el lenguaje. Los valores que puede manipular explícitamente son solo de los 6 tipos que enumeré).

La especificación utiliza la notación "Tipo (x)" cuando quiere hablar sobre "el tipo de x". Esta es solo una notación utilizada dentro de la especificación: no es una característica del lenguaje.

Como aclaran otras respuestas, en la práctica es posible que desee saber más que el tipo de un valor, especialmente cuando el tipo es Objeto. Independientemente, y para completar, aquí hay una implementación simple de JavaScript de Tipo (x) como se usa en la especificación:

function Type(x) { 
    if (x === null) {
        return 'Null';
    }

    switch (typeof x) {
    case 'undefined': return 'Undefined';
    case 'boolean'  : return 'Boolean';
    case 'number'   : return 'Number';
    case 'string'   : return 'String';
    default         : return 'Object';
    }
}
Wes
fuente
También hay símbolos
Juan Mendes
No en ECMAScript 5.1, no lo hay.
Wes
6

Me resulta frustrante que typeofsea ​​tan limitado. Aquí hay una versión mejorada:

var realtypeof = function (obj) {
    switch (typeof(obj)) {
        // object prototypes
        case 'object':
            if (obj instanceof Array)
                return '[object Array]';
            if (obj instanceof Date)
                return '[object Date]';
            if (obj instanceof RegExp)
                return '[object regexp]';
            if (obj instanceof String)
                return '[object String]';
            if (obj instanceof Number)
                return '[object Number]';

            return 'object';
        // object literals
        default:
            return typeof(obj);
    }   
};

prueba de muestra:

realtypeof( '' ) // "string"
realtypeof( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]" 
Tom Söderlund
fuente
3

Para los tipos JS incorporados puede usar:

function getTypeName(val) {
    return {}.toString.call(val).slice(8, -1);
}

Aquí usamos el método 'toString' de la clase 'Object' que funciona de manera diferente al mismo método de otros tipos.

Ejemplos:

// Primitives
getTypeName(42);        // "Number"
getTypeName("hi");      // "String"
getTypeName(true);      // "Boolean"
getTypeName(Symbol('s'))// "Symbol"
getTypeName(null);      // "Null"
getTypeName(undefined); // "Undefined"

// Non-primitives
getTypeName({});            // "Object"
getTypeName([]);            // "Array"
getTypeName(new Date);      // "Date"
getTypeName(function() {}); // "Function"
getTypeName(/a/);           // "RegExp"
getTypeName(new Error);     // "Error"

Si necesita un nombre de clase, puede usar:

instance.constructor.name

Ejemplos:

({}).constructor.name       // "Object"
[].constructor.name         // "Array"
(new Date).constructor.name // "Date"

function MyClass() {}
let my = new MyClass();
my.constructor.name         // "MyClass"

Pero esta característica se agregó en ES2015 .

WebBrother
fuente
1

Aquí está la solución completa.

También puede usarlo como una clase de ayuda en sus proyectos.

"use strict";
/**
 * @description Util file
 * @author Tarandeep Singh
 * @created 2016-08-09
 */

window.Sys = {};

Sys = {
  isEmptyObject: function(val) {
    return this.isObject(val) && Object.keys(val).length;
  },
  /** This Returns Object Type */
  getType: function(val) {
    return Object.prototype.toString.call(val);
  },
  /** This Checks and Return if Object is Defined */
  isDefined: function(val) {
    return val !== void 0 || typeof val !== 'undefined';
  },
  /** Run a Map on an Array **/
  map: function(arr, fn) {
    var res = [],
      i = 0;
    for (; i < arr.length; ++i) {
      res.push(fn(arr[i], i));
    }
    arr = null;
    return res;
  },
  /** Checks and Return if the prop is Objects own Property */
  hasOwnProp: function(obj, val) {
    return Object.prototype.hasOwnProperty.call(obj, val);
  },
  /** Extend properties from extending Object to initial Object */
  extend: function(newObj, oldObj) {
    if (this.isDefined(newObj) && this.isDefined(oldObj)) {
      for (var prop in oldObj) {
        if (this.hasOwnProp(oldObj, prop)) {
          newObj[prop] = oldObj[prop];
        }
      }
      return newObj;
    } else {
      return newObj || oldObj || {};
    }
  }
};

// This Method will create Multiple functions in the Sys object that can be used to test type of
['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Object', 'Array', 'Undefined']
.forEach(
  function(name) {
    Sys['is' + name] = function(obj) {
      return toString.call(obj) == '[object ' + name + ']';
    };
  }
);
<h1>Use the Helper JavaScript Methods..</h1>
<code>use: if(Sys.isDefined(jQuery){console.log("O Yeah... !!");}</code>

Para el módulo exportable CommonJs o el módulo RequireJS ...

"use strict";

/*** Helper Utils ***/

/**
 * @description Util file :: From Vault
 * @author Tarandeep Singh
 * @created 2016-08-09
 */

var Sys = {};

Sys = {
    isEmptyObject: function(val){
        return this.isObject(val) && Object.keys(val).length;
    },
    /** This Returns Object Type */
    getType: function(val){
        return Object.prototype.toString.call(val);
    },
    /** This Checks and Return if Object is Defined */
    isDefined: function(val){
        return val !== void 0 || typeof val !== 'undefined';
    },
    /** Run a Map on an Array **/
    map: function(arr,fn){
        var res = [], i=0;
        for( ; i<arr.length; ++i){
            res.push(fn(arr[i], i));
        }
        arr = null;
        return res;
    },
    /** Checks and Return if the prop is Objects own Property */
    hasOwnProp: function(obj, val){
        return Object.prototype.hasOwnProperty.call(obj, val);
    },
    /** Extend properties from extending Object to initial Object */
    extend: function(newObj, oldObj){
        if(this.isDefined(newObj) && this.isDefined(oldObj)){
            for(var prop in oldObj){
                if(this.hasOwnProp(oldObj, prop)){
                    newObj[prop] = oldObj[prop];
                }
            }
            return newObj;
        }else {
            return newObj || oldObj || {};
        }
    }
};

/**
 * This isn't Required but just makes WebStorm color Code Better :D
 * */
Sys.isObject
    = Sys.isArguments
    = Sys.isFunction
    = Sys.isString
    = Sys.isArray
    = Sys.isUndefined
    = Sys.isDate
    = Sys.isNumber
    = Sys.isRegExp
    = "";

/** This Method will create Multiple functions in the Sys object that can be used to test type of **/

['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Object', 'Array', 'Undefined']
    .forEach(
        function(name) {
            Sys['is' + name] = function(obj) {
                return toString.call(obj) == '[object ' + name + ']';
            };
        }
    );


module.exports = Sys;

Actualmente en uso en un repositorio público de git. Proyecto Github

Ahora puede importar este código Sys en un archivo Sys.js. entonces puede usar estas funciones de objeto Sys para descubrir el tipo de Objetos JavaScript

también puede verificar si el objeto está definido o el tipo es función o el objeto está vacío ... etc.

  • Sys.isObject
  • Sys.is Argumentos
  • Sys.isFunction
  • Sys.isString
  • Sys.isArray
  • Sys.is Indefinido
  • Sys.isDate
  • Sys.isNumber
  • Sys.isRegExp

Por ejemplo

var m = function(){};
Sys.isObject({});
Sys.isFunction(m);
Sys.isString(m);

console.log(Sys.isDefined(jQuery));
Tarandeep Singh
fuente
1

En JavaScript todo es un objeto

console.log(type of({}))  //Object
console.log(type of([]))  //Object

Para obtener el tipo Real , use esto

console.log(Object.prototype.toString.call({}))   //[object Object]
console.log(Object.prototype.toString.call([]))   //[object Array]

Espero que esto ayude

yogendra saxena
fuente