Znajdowanie typu zmiennej w JavaScript

146

W Javie możesz użyć instanceOflub getClass()na zmiennej, aby sprawdzić jej typ.

Jak znaleźć typ zmiennej w JavaScript, która nie jest silnie wpisana?

Na przykład, skąd mam wiedzieć, czy barjest a, Booleana Numberlub a String?

function foo(bar) {
    // what do I do here?
}
Tom Tucker
źródło
zobacz także: stackoverflow.com/questions/24318654
dreftymac.

Odpowiedzi:

242

Zastosowanie typeof:

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

Możesz więc:

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

Uważaj jednak, jeśli definiujesz te prymitywy za pomocą ich opakowań obiektów (czego nigdy nie powinieneś robić, używaj literałów, jeśli to możliwe):

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

Typ tablicy jest nadal object. Tutaj naprawdę potrzebujesz instanceofoperatora.

Aktualizacja:

Innym interesującym sposobem jest zbadanie wyników 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]"

Dzięki temu nie musiałbyś rozróżniać prymitywnych wartości i obiektów.

Felix Kling
źródło
Jaka byłaby wada użycia proto .constructor.name, a potrójna funkcja to: function getVariableType (object) {return (object .__ proto__.constructor.name); }
Stu
aktualizacja definicji funkcji, którą wymieniłem powyżej: function getVariableType (object) {return (object === undefined? "Undefined": object.__proto__.constructor.name);
Stu
29

typeof nadaje się tylko do zwracania typów „pierwotnych”, takich jak liczba, wartość logiczna, obiekt, ciąg znaków i symbole. Możesz również użyć instanceofdo sprawdzenia, czy obiekt jest określonego typu.

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

var obj = new MyObj(10);

console.log(obj instanceof MyObj && obj instanceof Object); // outputs true
Juan Mendes
źródło
23

Używając 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
źródło
Nie ma problemów z używaniem Number(1), Boolean(true)...Jedyne problemy występują, gdy używasz newi tworzony jest obiekt w pudełku, używanie ich jako funkcji może być w rzeczywistości przydatne przy konwersji z innych typów. Boolean(0) === false, Number(true) === 1
Juan Mendes,
o czym null? typeof nulljest „przedmiotem”
Dheeraj
15

W Javascript możesz to zrobić za pomocą funkcji typeof

function foo(bar){
  alert(typeof(bar));
}
wajiw
źródło
3
Jak wspomniałem w mojej odpowiedzi, typof zwróci tylko liczbę, wartość logiczną, obiekt, ciąg. Nie jest przydatne do określania innych typów, takich jak Array, RegExp lub typy niestandardowe.
Juan Mendes,
7

By być trochę bardziej precyzyjnym ECMAScript-5.1 niż inne odpowiedzi (niektórzy mogą powiedzieć pedantyczny):

W JavaScript zmienne (i właściwości) nie mają typów: wartości mają. Ponadto istnieje tylko 6 typów wartości: Undefined, Null, Boolean, String, Number i Object. (Z technicznego punktu widzenia istnieje również 7 „typów specyfikacji”, ale nie można przechowywać wartości tych typów jako właściwości obiektów lub wartości zmiennych - są one używane tylko w samej specyfikacji, aby zdefiniować sposób działania języka. Wartości możesz jawnie manipulować tylko spośród 6 typów, które wymieniłem).

Specyfikacja używa notacji „Typ (x)”, gdy chce mówić o „typie x”. To jest tylko notacja używana w specyfikacji: nie jest to cecha języka.

Jak wyjaśniają inne odpowiedzi, w praktyce możesz chcieć wiedzieć więcej niż typ wartości - szczególnie gdy typem jest Object. Niezależnie od tego i dla kompletności, oto prosta implementacja Type (x) w języku JavaScript, tak jak jest ona używana w specyfikacji:

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
źródło
Są też symbole
Juan Mendes
Nie w ECMAScript 5.1, nie ma.
Wes,
6

To frustrujące, że typeofjest to tak ograniczone. Oto ulepszona wersja:

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 próbny:

realtypeof( '' ) // "string"
realtypeof( new String('') ) // "[object String]"
Object.prototype.toString.call("foo bar") //"[object String]" 
Tom Söderlund
źródło
3

Dla wbudowanych typów JS możesz użyć:

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

Tutaj używamy metody „toString” z klasy „Object”, która działa inaczej niż ta sama metoda innych typów.

Przykłady:

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

Jeśli potrzebujesz nazwy zajęć, możesz użyć:

instance.constructor.name

Przykłady:

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

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

Ale ta funkcja została dodana w ES2015 .

WebBrother
źródło
1

Oto kompletne rozwiązanie.

Możesz również użyć go jako klasy pomocniczej w swoich projektach.

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

W przypadku eksportowalnego modułu CommonJs lub modułu 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;

Obecnie w użyciu w publicznym repozytorium git. Projekt Github

Teraz możesz zaimportować ten kod Sys do pliku Sys.js. następnie możesz użyć funkcji obiektu Sys, aby dowiedzieć się, jakiego typu są obiekty JavaScript

możesz również sprawdzić, czy obiekt jest zdefiniowany, czy typ to Funkcja, czy też obiekt jest pusty ... itd.

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

Na przykład

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

console.log(Sys.isDefined(jQuery));
Tarandeep Singh
źródło
1

W JavaScript wszystko jest przedmiotem

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

Aby uzyskać typ rzeczywisty , użyj tego

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

Mam nadzieję że to pomoże

yogendra saxena
źródło