我创建了一个 JavaScript 对象,但如何确定该对象的类?
我想要类似于 Java 的.getClass()
方法的东西。
我创建了一个 JavaScript 对象,但如何确定该对象的类?
我想要类似于 Java 的.getClass()
方法的东西。
getClass()
JavaScript 中没有与 Java 完全相同的对应物。这主要是因为 JavaScript 是一种基于原型的语言,而不是 Java 是一种基于类的语言。
根据您的需要getClass()
,JavaScript 中有几个选项:
typeof
instanceof
obj.
constructor
func.
prototype
, proto
.isPrototypeOf
几个例子:
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
参数,您可以使用gulp或grunt将其设置为 false 。
obj.constructor.name
在现代浏览器中是一种可靠的方法。Function.name
在 ES6 中正式添加到标准中,使其成为将 JavaScript 对象的“类”作为字符串获取的符合标准的方法。如果对象是用 实例化的var obj = new MyClass()
,它将返回“MyClass”。
它将返回数字的“Number”,数组的“Array”和函数的“Function”等。它通常按预期运行。唯一失败的情况是对象是在没有原型的情况下创建的,通过Object.create( null )
,或者对象是从匿名定义(未命名)函数实例化的。
另请注意,如果您正在缩小代码,则与硬编码类型字符串进行比较是不安全的。例如,不是检查 if 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...
要获得“伪类”,您可以通过构造函数获得
obj.constructor
假设constructor
在您进行继承时正确设置了 - 这类似于:
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
和这两行,连同:
var woofie = new Dog()
将woofie.constructor
指向Dog
. 请注意,它Dog
是一个构造函数,并且是一个Function
对象。但是你可以做到if (woofie.constructor === Dog) { ... }
。
如果您想将类名作为字符串获取,我发现以下方法运行良好:
http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects
function getObjectClass(obj) {
if (obj && obj.constructor && obj.constructor.toString) {
var arr = obj.constructor.toString().match(
/function\s*(\w+)/);
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
}
它获取构造函数,将其转换为字符串,并提取构造函数的名称。
请注意,这obj.constructor.name
可能运作良好,但它不是标准的。它适用于 Chrome 和 Firefox,但不适用于 IE,包括 IE 9 或 IE 10 RTM。
您可以使用构造函数属性获取对创建对象的构造函数的引用:
function MyObject(){
}
var obj = new MyObject();
obj.constructor; // MyObject
如果需要在运行时确认对象的类型,可以使用instanceof运算符:
obj instanceof MyObject // true