Localizando tipo variável em JavaScript

146

Em Java, você pode usar instanceOfou getClass()em uma variável para descobrir seu tipo.

Como descubro o tipo de uma variável no JavaScript que não é fortemente tipado?

Por exemplo, como sei se baré um Booleanou a Numberou a String?

function foo(bar) {
    // what do I do here?
}
Tom Tucker
fonte
Veja também: stackoverflow.com/questions/24318654
dreftymac

Respostas:

242

Use typeof:

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

Então você pode fazer:

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

Tenha cuidado, porém, se você definir essas primitivas com seus invólucros de objetos (o que você nunca deve fazer, use literais sempre que possível):

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

O tipo de uma matriz ainda é object. Aqui você realmente precisa do instanceofoperador.

Atualizar:

Outra maneira interessante é examinar a saída 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]"

Com isso, você não precisaria distinguir entre valores e objetos primitivos.

Felix Kling
fonte
Qual seria o lado negativo de usar proto .constructor.name e uma função simples seria: function getVariableType (objeto) {return (objeto .__ proto__.constructor.name); }
Stu
atualizar para a definição de função listada acima: function getVariableType (object) {return (object === undefined? "Undefined": object.__proto__.constructor.name);
Stu
29

typeof é bom apenas para retornar os tipos "primitivos", como número, booleano, objeto, string e símbolos. Você também pode usar instanceofpara testar se um objeto é de um 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
fonte
23

Usando 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
fonte
Não há problemas com o uso Number(1), Boolean(true)...Os únicos problemas são quando você usa newe um objeto em caixa é criado, usá-los como funções pode ser realmente útil na conversão de outros tipos. Boolean(0) === false, Number(true) === 1
Juan Mendes
que tal null? typeof nullé 'objeto'
Dheeraj
15

Em Javascript, você pode fazer isso usando a função typeof

function foo(bar){
  alert(typeof(bar));
}
wajiw
fonte
3
Como mencionei na minha resposta, typof retornará apenas number, boolean, object, string. Não é útil para determinar outros tipos, como Array, RegExp ou tipos personalizados.
Juan Mendes
7

Para ser um pouco mais preciso do ECMAScript-5.1 do que as outras respostas (alguns podem dizer pedantes):

Em JavaScript, variáveis ​​(e propriedades) não têm tipos: os valores possuem. Além disso, existem apenas 6 tipos de valores: Indefinido, Nulo, Booleano, String, Número e Objeto. (Tecnicamente, também existem 7 "tipos de especificação", mas você não pode armazenar valores desses tipos como propriedades de objetos ou valores de variáveis ​​- eles são usados ​​apenas dentro da própria especificação para definir como a linguagem funciona. você pode manipular explicitamente são apenas dos 6 tipos listados.)

A especificação usa a notação "Tipo (x)" quando deseja falar sobre "o tipo de x". Esta é apenas uma notação usada dentro das especificações: não é um recurso do idioma.

Como outras respostas deixam claro, na prática você pode querer saber mais do que o tipo de um valor - principalmente quando o tipo é Objeto. Independentemente, e para ser completo, aqui está uma implementação JavaScript simples do Type (x), conforme é usada na especificação:

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
fonte
Também existem símbolos #
Juan Mendes
Não no ECMAScript 5.1, não há.
217 Wes Wes
6

Acho frustrante que typeofseja tão limitado. Aqui está uma versão melhorada:

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);
    }   
};

teste de amostra:

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

Para tipos JS internos, você pode usar:

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

Aqui usamos o método 'toString' da classe 'Object', que funciona diferente do mesmo método de outros tipos.

Exemplos:

// 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"

Se você precisar de um nome de classe, poderá usar:

instance.constructor.name

Exemplos:

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

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

Mas esse recurso foi adicionado no ES2015 .

WebBrother
fonte
1

Aqui está a solução completa.

Você também pode usá-lo como uma classe auxiliar em seus projetos.

"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 o módulo CommonJs exportável ou o 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;

Atualmente em uso em um repositório público de git. Projeto Github

Agora você pode importar esse código Sys em um arquivo Sys.js. você pode usar essas funções de objeto Sys para descobrir o tipo de objetos JavaScript

você também pode verificar se o objeto está definido ou o tipo é função ou o objeto está vazio ... etc.

  • Sys.isObject
  • Sys.isArguments
  • Sys.isFunction
  • Sys.isString
  • Sys.isArray
  • Sys.isUndefined
  • Sys.isDate
  • Sys.isNumber
  • Sys.isRegExp

Por exemplo

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

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

Em JavaScript, tudo é um objeto

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

Para obter o tipo Real , use este

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

Espero que isto ajude

yogendra saxena
fonte