如何在Javascript中检查实例的类?

31

可能是重复问题:
如何获取JavaScript对象的类?


在Ruby中,我可以这样做来检查一个实例的类:

'this is an string'.class

=>String

在JavaScript中有类似的东西吗?


参见 https://dev59.com/FlXTa4cB1Zd3GeqP0EYK - Brad Christie
这个问题和被接受的答案似乎是相关的。 - Jose Quijada
4个回答

48

你可能指的是类型或构造函数,而不是 class。在 JavaScript 中,class 有不同的含义。

要获取类:

var getClassOf = Function.prototype.call.bind(Object.prototype.toString);
getClassOf(new Date());     // => "[object Date]"
getClassOf('test string');  // => "[object String]"
getClassOf({ x: 1 });       // => "[object Object]"
getClassOf(function() { }); // => "[object Function]"

请参阅相关的 MDN 文章。

要获取构造函数或原型,有几种不同的方法,具体取决于你所需的内容。

要确定你拥有的是哪种基元类型,请使用 typeof。对于字符串、布尔值、数字等基元类型,这是最好的方法:

typeof 'test string';  // => 'string'
typeof 3;              // => 'number'
typeof false;          // => 'boolean'
typeof function() { }; // => 'function'
typeof { x: 1 };       // => 'object'
typeof undefined;      // => 'undefined'

请注意,在这种情况下,null 的行为很奇怪,因为typeof null会返回"object"而不是"null"

您还可以使用Object.getPrototypeOf(myObject)(或在某些浏览器中使用myObject.__proto__myObject.constructor.prototype)来获取原型,即JavaScript继承的骨干。

您可以使用instanceof测试构造函数:

new Date() instanceof Date;  // => true

你还可以通过myObject.constructor来合理地获取构造函数,但请注意这可能会被更改。要获取构造函数的名称,请使用myObject.constructor.name

new Date().constructor.name;   // => 'Date'

@KooiInc 它可以工作;它返回的是class,即Object。如果你想要构造函数,你可以使用instanceofconstructor.name。这不是它是否能工作的问题。这是关于你是否理解JavaScript中类的概念的问题(请看我在帖子开头的注释,“你可能指的是类型或构造函数,而不是类”)。 - Nathan Wall
@wnwall:new function CC(){}() 的构造函数是 CC,当然最终是 Object,但这并不是很有信息量。我认为我理解了 Javascript 中的“类”。就像:你可以模拟它,但没有必要这样做。请参见我的回答底部的链接。 - KooiInc
@KooiInc:[[Class]]在JavaScript中有着非常技术性的含义,描述了一个对象可能属于的非常有限的“类”:Function、Array、Boolean、Number、RegExp等。如果该对象是自定义构造函数的实例,则它属于Object类。请参见http://perfectionkills.com/category/class/。具体搜索`[[Class]]`或`Object.prototype.toString`。此外,请参阅我在原始帖子中引用的MDN文章。 - Nathan Wall
1
@wnwall——instanceOf和构造函数属性都不可靠,特别是对于宿主对象(如DOM对象)。并非所有JavaScript对象都继承自Object或是其实例(例如某些浏览器中的某些宿主对象)。如果在JavaScript中,您需要发现一个对象的“类”,那么您可能正在错误地处理事情。 - RobG
1
我并不是在争论大多数情况下都应该使用类信息,正如我所说,OP可能正在寻找构造函数信息。但是类信息可以很有帮助,了解它也是为了完整性。JavaScript本身就是使用[[Class]]信息实现的。ES3规范中Date.prototype.getTime指定应基于[[Class]]检查参数。他们使用类而不是构造函数/原型信息。在跨框架对象中,它也可以提供帮助。你为什么要争论扩展对JavaScript复杂性的更好知识和理解呢? - Nathan Wall
显示剩余3条评论

19

不确定所有浏览器是否都适用,但您可以使用constructor.name

'some string'.constructor.name; //=>String
({}).constructor.name           //=>Object
(7.3).constructor.name          //=>Number
[].constructor.name             //=>Array
(function(){}).constructor.name //=>Function
true.constructor.name           //=>Boolean
/test/i.constructor.name        //=>RegExp
(new Date).constructor.name     //=>Date
(new function MyConstructor(){}())
  .constructor.name;            //=>MyConstructor

尽管在 JavaScript 中,Object 是所有对象的祖先,但你可以扩展它(这样做有利有弊参考链接)。

Object.prototype.class = function(){
  return this.constructor.name;
}
'some string'.class(); //=>String
(23).class();          //=>Number
// etc...
注意: JavaScript不支持“类”1,它的继承模型是原型式的。请参阅原型式继承了解更多。

1 来自ECMAScript标准。

ECMAScript不使用C++、Smalltalk或Java中的类。相反,对象可以通过各种方式创建,包括通过文字表示法或通过构造函数创建对象,然后执行代码来初始化它们的所有或部分属性的初始值。每个构造函数都是具有名为prototype的属性的函数,用于实现基于原型的继承和共享属性。对象是通过在new表达式中使用构造函数创建的;例如,new Date(2009,11)创建一个新的Date对象。如果不使用new调用构造函数,则会产生取决于构造函数的后果。例如,Date()会产生当前日期和时间的字符串表示形式,而不是对象。


1
+1 指出了 JavaScript 中 object 的不同含义,对原型的参考也很好。 - mko
请注意,在React应用程序中不应使用constructor.name。当生成捆绑包时,类将被最小化,并且不会匹配。我已经在两个不同的项目中遇到了这个问题 :) - Kostanos

4
在 JavaScript 中,你可以使用以下语法:
typeof

等同于

var a="this is string";
typeof a; // return "string"

function abc(){}
typeof abc; // return "function"

var a = {a:1,b:2,c:3}
typeof a; return "object"

1
+1 虽然不完美,但 typeof 比所有其他建议的方法更可靠。 - RobG

3

typeof and instanceof is what you need

> x = "Hello, World!"
"Hello, World!"
> typeof x
"string"

您可以检查构造函数名称以获取构造函数类的名称(或者您称之为类):
> x.constructor.name
> "String"

那个应该只返回 object,对吧?那不会告诉你类的名称(虽然我不确定 OP 是否需要)。 - Brad Christie
它也适用于DOM对象吗?element = document.getElementById('foo'); typeof element; 它返回"object",这是父类而不是document.element - mko
@BradChristie 是的,那就是我刚刚发现的。你有更好的解决方案吗? - mko
@Nemoden:我知道,但原始问题表述不清楚;我不确定仅仅知道它是一个对象是否足够,还是OP想要它来自哪个名称。例如:var foo = new Bar(); 然后确定 someMagic(foo) 的结果是发现它是 Bar 的一个实例。 - Brad Christie
1
@Nemoden var MyConstructor = function(){};var instance = new MyConstructor;console.log(instance.constructor.name);/*""*/ - Rob W
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接