检查JS对象类型的最准确方法是什么?

时间:2011-10-25 18:06:30

标签: javascript

typeof运算符实际上并没有帮助我们找到对象的真实类型。

我已经看过以下代码:

Object.prototype.toString.apply(t)  

问题:

检查对象类型的准确方法吗?

9 个答案:

答案 0 :(得分:162)

JavaScript规范提供了一种确定对象类的正确方法:

Object.prototype.toString.call(t);

http://bonsaiden.github.com/JavaScript-Garden/#types

答案 1 :(得分:57)

Object.prototype.toString是一种很好的方式,但其性能最差。

http://jsperf.com/check-js-type

check js type performance

使用typeof解决一些基本问题(String,Number,Boolean ...)并使用Object.prototype.toString来解决复杂的问题(如Array,Date,RegExp)。

这是我的解决方案:

var type = (function(global) {
    var cache = {};
    return function(obj) {
        var key;
        return obj === null ? 'null' // null
            : obj === global ? 'global' // window in browser or global in nodejs
            : (key = typeof obj) !== 'object' ? key // basic: string, boolean, number, undefined, function
            : obj.nodeType ? 'object' // DOM element
            : cache[key = ({}).toString.call(obj)] // cached. date, regexp, error, object, array, math
            || (cache[key] = key.slice(8, -1).toLowerCase()); // get XXXX from [object XXXX], and cache it
    };
}(this));

用作:

type(function(){}); // -> "function"
type([1, 2, 3]); // -> "array"
type(new Date()); // -> "date"
type({}); // -> "object"

答案 2 :(得分:13)

接受的答案是正确的,但我喜欢在我构建的大多数项目中定义这个小实用程序。

var types = {
   'get': function(prop) {
      return Object.prototype.toString.call(prop);
   },
   'null': '[object Null]',
   'object': '[object Object]',
   'array': '[object Array]',
   'string': '[object String]',
   'boolean': '[object Boolean]',
   'number': '[object Number]',
   'date': '[object Date]',
}

像这样使用:

if(types.get(prop) == types.number) {

}

如果你正在使用角度,你甚至可以干净地注射它:

angular.constant('types', types);

答案 3 :(得分:10)

var o = ...
var proto =  Object.getPrototypeOf(o);
proto === SomeThing;

保留您希望对象具有的原型的句柄,然后与之进行比较。

例如

var o = "someString";
var proto =  Object.getPrototypeOf(o);
proto === String.prototype; // true

答案 4 :(得分:2)

找出对象的REAL类型的最佳方法(包括原生对象或数据类型名称(如String,Date,Number,..等)和对象的REAL类型(甚至是自定义的);通过获取对象原型的构造函数的name属性:

原生类型Ex1:

var string1 = "Test";
console.log(string1.__proto__.constructor.name);

显示:

String

练习2:

var array1 = [];
console.log(array1.__proto__.constructor.name);

显示:

Array

自定义类:

function CustomClass(){
  console.log("Custom Class Object Created!");
}
var custom1 = new CustomClass();

console.log(custom1.__proto__.constructor.name);

显示:

CustomClass

答案 5 :(得分:2)

我认为这里显示的大部分解决方案都受到过度设计的影响。检查值是否为[object Object]类型的最简单方法可能是检查它的.constructor属性:

function isObject (a) { return a != null && a.constructor === Object; }
使用箭头功能

甚至更短:

const isObject = a => a != null && a.constructor === Object;

a != null部分是必要的,因为可能会传入nullundefined而您无法从其中任何一个中提取构造函数属性。

它适用于通过以下方式创建的任何对象:

  • Object构造函数
  • 文字{}

它的另一个优点是,它能够为使用Symbol.toStringTag的自定义类提供正确的报告。例如:

class MimicObject {
  get [Symbol.toStringTag]() {
    return 'Object';
  }
}

这里的问题是,当在其实例上调用Object.prototype.toString时,将返回错误报告[object Object]

let fakeObj = new MimicObject();
Object.prototype.toString.call(fakeObj); // -> [object Object]

但是检查构造函数会得到正确的结果:

let fakeObj = new MimicObject();
fakeObj.constructor === Object; // -> false

答案 6 :(得分:1)

我知道一个老问题。您不需要转换它。查看此功能:

function getType( oObj )
{
    if( !!oObj && typeof oObj === "object" )
    {
       // Check if it is an alien object, for example created as {world:'hello'}
       if( typeof oObj.constructor !== "function" )
        { return 'Object'; }

      return oObj.constructor.name; 
    }   

    return false;
}; 

示例:

function MyObject() {}; // Just for example

console.log( getType( new String( "hello ") )); // String
console.log( getType( function() {} ));         // Function
console.log( getType( {} ));                    // Object
console.log( getType( new MyObject() ));        // MyObject

成本低廉且简单。

答案 7 :(得分:1)

最佳解决方案toString(如上所述):

function getRealObjectType(obj: {}): string {
    return Object.prototype.toString.call(obj).match(/\[\w+ (\w+)\]/)[1].toLowerCase();
}

enter image description here

正当警告:toString认为NaNnumber,因此以后必须手动使用Number.isNaN(value)进行保护。

建议使用另一种解决方案,将Object.getPrototypeOfnullundefined 结合使用

Using constructor

答案 8 :(得分:0)

我整理了一个受上述正确答案启发的小型检查实用程序:

thetypeof = function(name) {
        let obj = {};
        obj.object = 'object Object'
        obj.array = 'object Array'
        obj.string = 'object String'
        obj.boolean = 'object Boolean'
        obj.number = 'object Number'
        obj.type = Object.prototype.toString.call(name).slice(1, -1)
        obj.name = Object.prototype.toString.call(name).slice(8, -1)
        obj.is = (ofType) => {
            ofType = ofType.toLowerCase();
            return (obj.type === obj[ofType])? true: false
        }
        obj.isnt = (ofType) => {
            ofType = ofType.toLowerCase();
            return (obj.type !== obj[ofType])? true: false
        }
        obj.error = (ofType) => {
            throw new TypeError(`The type of ${name} is ${obj.name}: `
            +`it should be of type ${ofType}`)
        }
        return obj;
    };

示例:

if (thetypeof(prop).isnt('String')) thetypeof(prop).error('String')
if (thetypeof(prop).is('Number')) // do something