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

Roy*_*mir 124 javascript

typeof运营商并没有真正帮助我们找到真正的类的一个对象.

我已经看过以下代码:

Object.prototype.toString.apply(t)  
Run Code Online (Sandbox Code Playgroud)

题:

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

kma*_*eny 169

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

Object.prototype.toString.call(t);
Run Code Online (Sandbox Code Playgroud)

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

  • 如果你正在寻找一个特定的类型,你可能想要做的事情:`Object.prototype.toString.call(new FormData())==="[object FormData]"`这将是真的.您还可以使用`slice(8,-1)`返回`FormData`而不是`[object FormData]` (4认同)
  • 使用`Object.prototype`和`{}`之间有什么区别吗? (3认同)
  • 也许这已经改变了多年,但是`Object.prototype.toString.call(new MyCustomObject())`返回`[object Object]`而`new MyCustomObject()instanceOf MyCustomObject返回true`这就是我想要的(Chrome 54.0) .2840.99米) (3认同)
  • 这就引出了一个问题,为什么他们不使用更方便的方法来包装此代码,或者不允许其他操作员对此进行编译。我知道您只是信使,但坦率地说那太糟糕了。 (2认同)

wik*_*iky 58

Object.prototype.toString是一个好方法,但它的表现是最糟糕的.

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

检查js类型性能

使用typeof解决一些基本问题(字符串,数字,布尔...),并使用Object.prototype.toString来解决复杂的东西(如数组,日期,正则表达式).

这是我的解决方案:

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));
Run Code Online (Sandbox Code Playgroud)

用于:

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

  • 应该通过一些常识来调整这些性能指标.当然,prototype.toString比其他的慢一个数量级,但在宏观方案中,每次调用平均需要几百纳秒*.除非在非常频繁执行的关键路径中使用此调用,否则这可能是无害的.我宁愿拥有直接的代码而不是快速完成1微秒的代码. (16认同)

par*_*ent 15

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

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]',
}
Run Code Online (Sandbox Code Playgroud)

像这样使用:

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

}
Run Code Online (Sandbox Code Playgroud)

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

angular.constant('types', types);
Run Code Online (Sandbox Code Playgroud)


Ray*_*nos 10

var o = ...
var proto =  Object.getPrototypeOf(o);
proto === SomeThing;
Run Code Online (Sandbox Code Playgroud)

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

例如

var o = "someString";
var proto =  Object.getPrototypeOf(o);
proto === String.prototype; // true
Run Code Online (Sandbox Code Playgroud)


bel*_*iha 5

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

本机类型 Ex1:

var string1 = "Test";
console.log(string1.__proto__.constructor.name);
Run Code Online (Sandbox Code Playgroud)

显示:

String
Run Code Online (Sandbox Code Playgroud)

例2:

var array1 = [];
console.log(array1.__proto__.constructor.name);
Run Code Online (Sandbox Code Playgroud)

显示:

Array
Run Code Online (Sandbox Code Playgroud)

定制类:

var string1 = "Test";
console.log(string1.__proto__.constructor.name);
Run Code Online (Sandbox Code Playgroud)

显示:

CustomClass
Run Code Online (Sandbox Code Playgroud)


Dav*_*vid 5

我认为这里显示的大多数解决方案都存在过度设计的问题。检查值是否为类型的最简单方法可能[object Object]是检查其.constructor属性:

function isObject (a) { return a != null && a.constructor === Object; }
Run Code Online (Sandbox Code Playgroud)

甚至使用箭头功能更短:

const isObject = a => a != null && a.constructor === Object;
Run Code Online (Sandbox Code Playgroud)

a != null部分是必需的,因为可能会传入null或,undefined并且您不能从这两个中的任何一个提取构造函数属性。

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

  • Object构造
  • 文字 {}

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

class MimicObject {
  get [Symbol.toStringTag]() {
    return 'Object';
  }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是,当调用Object.prototype.toString它的一个实例时,[object Object]将返回错误的报告:

let fakeObj = new MimicObject();
Object.prototype.toString.call(fakeObj); // -> [object Object]
Run Code Online (Sandbox Code Playgroud)

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

let fakeObj = new MimicObject();
fakeObj.constructor === Object; // -> false
Run Code Online (Sandbox Code Playgroud)