协慌网

登录 贡献 社区

如何获取 JavaScript 对象的类?

我创建了一个 JavaScript 对象,但是如何确定该对象的类呢?

我想要类似于 Java 的.getClass()方法。

答案

JavaScript 中没有与 Java 的getClass()通常,这是由于 JavaScript 是基于原型的语言,而不是 Java 是基于类的语言。

根据您需要getClass()的不同,JavaScript 中有几个选项:

几个例子:

function Foo() {}
var foo = new Foo();

typeof Foo;             // == "function"
typeof foo;             // == "object"

foo instanceof Foo;     // == true
foo.constructor.name;   // == "Foo"
Foo.name                // == "Foo"    

Foo.prototype.isPrototypeOf(foo);   // == true

Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21);            // == 42

注意:如果使用 Uglify 编译代码,它将更改非全局类名。为了防止这种情况,Uglify 有一个--mangle参数,您可以使用gulpgrunt将其设置为 false。

obj.constructor.name

在现代浏览器中是一种可靠的方法。 Function.name已正式添加到标准中,这使其成为符合标准的方法,可将 JavaScript 对象的 “类” 作为字符串获取。 var obj = new MyClass()实例化该对象,则它将返回 “MyClass”。

它将为数字返回 “Number”,为数组返回 “Array”,为函数返回 “Function”,等等。它的行为通常与预期的一样。失败的唯一情况是通过Object.create( null )创建了没有原型的对象,或者该对象是从匿名定义(未命名)的函数实例化的。

另请注意,如果要压缩代码,则与硬编码类型字符串进行比较是不安全的。例如,不是检查obj.constructor.name == "MyType" ,而是检查obj.constructor.name == MyType.name 。或者只是比较构造函数本身,但是这将无法跨 DOM 边界,因为每个 DOM 上都有不同的构造函数实例,因此无法在其构造函数上进行对象比较。

此 getNativeClass()函数对于未定义的值"undefined" ,对于 null "null"
对于所有其它的值,则CLASSNAME -part 摘自[object CLASSNAME]这是使用的结果Object.prototype.toString.call(value)

getAnyClass()行为与 getNativeClass()相同,但也支持自定义构造函数

function getNativeClass(obj) {
  if (typeof obj === "undefined") return "undefined";
  if (obj === null) return "null";
  return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
}

function getAnyClass(obj) {
  if (typeof obj === "undefined") return "undefined";
  if (obj === null) return "null";
  return obj.constructor.name;
}

getClass("")   === "String";
getClass(true) === "Boolean";
getClass(0)    === "Number";
getClass([])   === "Array";
getClass({})   === "Object";
getClass(null) === "null";

getAnyClass(new (function Foo(){})) === "Foo";
getAnyClass(new class Foo{}) === "Foo";

// etc...