Trovare il tipo di variabile in JavaScript


146

In Java, puoi usare instanceOf o getClass()su una variabile per scoprirne il tipo.

Come faccio a scoprire il tipo di una variabile in JavaScript che non è fortemente tipizzato?

Ad esempio, come faccio a sapere se barè a Booleano a Numbero a String?

function foo(bar) {
    // what do I do here?
}

Risposte:


242

Utilizzare typeof:

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

Quindi puoi fare:

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

Fai attenzione, però, se definisci queste primitive con i loro wrapper di oggetti (cosa che non dovresti mai fare, usa i valori letterali ove possibile):

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

Il tipo di un array è fermo object. Qui hai davvero bisogno instanceofdell'operatore.

Aggiornare:

Un altro modo interessante è esaminare l'output di 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 ciò non dovresti distinguere tra valori primitivi e oggetti.


Quale sarebbe il lato negativo dell'uso di proto .constructor.name una funzione siple sarebbe: function getVariableType (object) {return (object .__ proto__.constructor.name); }
Stu

aggiornamento alla definizione della funzione che ho elencato sopra: funzione getVariableType (oggetto) {return (oggetto === undefined? "Undefined": object.__proto__.constructor.name);
Stu

29

typeof è utile solo per restituire i tipi "primitivi" come numero, valore booleano, oggetto, stringa e simboli. Puoi anche usare instanceofper verificare se un oggetto è di un tipo specifico.

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

var obj = new MyObj(10);

console.log(obj instanceof MyObj && obj instanceof Object); // outputs true

23

Utilizzando 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';

Non ci sono problemi con l'uso. Number(1), Boolean(true)...Gli unici problemi sono quando si usa newe viene creato un oggetto in scatola, usarli come funzioni può essere effettivamente utile per la conversione da altri tipi. Boolean(0) === false, Number(true) === 1
Juan Mendes,

che dire null? typeof nullè "oggetto"
Dheeraj,

15

In Javascript puoi farlo usando la funzione typeof

function foo(bar){
  alert(typeof(bar));
}

3
Come ho detto nella mia risposta, typof restituirà solo numero, valore booleano, oggetto, stringa. Non utile per determinare altri tipi, come Array, RegExp o tipi personalizzati.
Juan Mendes,

7

Per essere un po 'più preciso di ECMAScript-5.1 rispetto alle altre risposte (alcuni potrebbero dire pedanti):

In JavaScript, le variabili (e le proprietà) non hanno tipi: i valori sì. Inoltre, ci sono solo 6 tipi di valori: Undefined, Null, Boolean, String, Number e Object. (Tecnicamente, ci sono anche 7 "tipi di specifica", ma non è possibile memorizzare valori di tali tipi come proprietà di oggetti o valori di variabili: vengono utilizzati solo all'interno della specifica stessa, per definire il funzionamento del linguaggio. I valori puoi manipolare esplicitamente solo i 6 tipi che ho elencato.)

La specifica usa la notazione "Tipo (x)" quando vuole parlare del "tipo di x". Questa è solo una notazione usata all'interno delle specifiche: non è una caratteristica della lingua.

Come chiariscono altre risposte, in pratica potresti voler conoscere più del tipo di un valore, in particolare quando il tipo è Object. Indipendentemente da ciò, e per completezza, ecco una semplice implementazione JavaScript di Tipo (x) come viene utilizzato nelle specifiche:

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

Ci sono anche simboli
Juan Mendes,

Non in ECMAScript 5.1, non ci sono.
Wes,

6

Trovo frustrante che typeofsia così limitato. Ecco una versione migliorata:

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

test di esempio:

realtypeof( '' ) // "string"
realtypeof( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]" 

3

Per i tipi JS integrati è possibile utilizzare:

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

Qui usiamo il metodo 'toString' dalla classe 'Object' che funziona in modo diverso rispetto allo stesso metodo di altri tipi.

Esempi:

// 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 hai bisogno di un nome di classe puoi usare:

instance.constructor.name

Esempi:

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

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

Ma questa funzione è stata aggiunta in ES2015 .


1

Ecco la soluzione completa.

Puoi anche usarlo come classe Helper nei tuoi progetti.

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

Per modulo CommonJs esportabile o modulo 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;

Attualmente in uso su un repository git pubblico. Progetto Github

Ora puoi importare questo codice Sys in un file Sys.js. quindi è possibile utilizzare le funzioni di questo oggetto Sys per scoprire il tipo di oggetti JavaScript

puoi anche controllare se l'oggetto è definito o il tipo è funzione o l'oggetto è vuoto ... ecc.

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

Per esempio

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

console.log(Sys.isDefined(jQuery));

1

In JavaScript tutto è un oggetto

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

Per ottenere il tipo reale , utilizzare questo

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

Spero che questo ti aiuti

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.