如何获得一个JavaScript对象的类?

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

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

JavaScript中没有与Java的getClass()完全相同的对象。 这主要是由于JavaScript是基于原型的语言 ,而Java是基于类的 。

根据你所需要的getClass() ,JavaScript中有几个选项:

  • typeof
  • instanceof
  • obj. constructor
  • func. prototypeprotoisPrototypeOf

几个例子:

 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参数,你可以设置为false使用gulp或grunt 。

 obj.constructor.name 

在现代浏览器的大多数情况下,尽pipeFunction.name没有正式添加到标准,直到ES6。 如果对象用var obj = new MyClass()实例化,它将以stringforms返回“MyClass”。

它会返回数字“数字”,数组返回“数组”和函数返回的“函数”等。这似乎是相当可靠的。 唯一失败的情况是如果通过Object.create( null )创build的对象没有原型,或者该对象是从匿名定义(未命名)函数实例化的。

可以说, obj.constructor.nametypeof更直观,可以封装在一个函数中,以处理constructor未定义(以及处理空引用)的奇怪情况。

注意:这个方法的另一个好处是它直接在DOM边界上工作,而不用直接比较构造函数对象或使用instanceOf 。 不能像你所期望的那样工作的原因是每个DOM上的构造函数实际上有不同的实例,因此在构造函数上做一个对象比较是行不通的。

注2:奇怪的是,这个方法似乎返回了原型链中使用的最基本函数的名字,这不幸并不直观。 例如,如果BA派生出原型,并且创build了B的新实例B ,则b.constructor.name返回“A”! 所以感觉完全倒退。 但是,它对单级原型和所有基元都能正常工作。

该函数从Object.prototype.toString.call(someObject) [object class] "undefined""null""class"

 function getClass(obj) { if (typeof obj === "undefined") return "undefined"; if (obj === null) return "null"; return Object.prototype.toString.call(obj) .match(/^\[object\s(.*)\]$/)[1]; } getClass("") === "String"; getClass(true) === "Boolean"; getClass(0) === "Number"; getClass([]) === "Array"; getClass({}) === "Object"; getClass(null) === "null"; // etc... 

要获得“伪类”,可以通过获取构造函数

 obj.constructor 

假设constructor在你inheritance的时候被正确地设置了 – 就像这样:

 Dog.prototype = new Animal(); Dog.prototype.constructor = Dog; 

这两条线连同:

 var woofie = new Dog() 

将使woofie.constructor指向Dog 。 请注意, Dog是一个构造函数,并且是一个Function对象。 但是,你可以做if (woofie.constructor === Dog) { ... }

如果你想获得类名作为string,我发现以下工作:

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; } 

它获取到构造函数,将其转换为string,并提取构造函数的名称。

请注意, obj.constructor.name可以运行良好,但不是标准的。 它在Chrome和Firefox上,但不在IE上,包括IE 9或IE 10 RTM。

您可以通过使用构造函数属性来获取对创build对象的构造函数的引用:

 function MyObject(){ } var obj = new MyObject(); obj.constructor; // MyObject 

如果您需要在运行时确认对象的types,则可以使用instanceof运算符:

 obj instanceof MyObject // true 

我发现在IE中object.constructor.toString()返回[object objectClass] ,而不是在chome中返回的function objectClass () {} 。 所以,我认为http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects中的代码可能在IE中不能正常工作。而且我修复了以下代码:;

码:

 var getObjectClass = function (obj) { if (obj && obj.constructor && obj.constructor.toString()) { /* * for browsers which have name property in the constructor * of the object,such as chrome */ if(obj.constructor.name) { return obj.constructor.name; } var str = obj.constructor.toString(); /* * executed if the return of object.constructor.toString() is * "[object objectClass]" */ if(str.charAt(0) == '[') { var arr = str.match(/\[\w+\s*(\w+)\]/); } else { /* * executed if the return of object.constructor.toString() is * "function objectClass () {}" * for IE Firefox */ var arr = str.match(/function\s*(\w+)/); } if (arr && arr.length == 2) { return arr[1]; } } return undefined; }; 

对于ES6中的Javascript类,您可以使用object.constructor 。 在下面的示例类中, getClass()方法返回ES6类,如您所期望的那样:

 var Cat = class { meow() { console.log("meow!"); } getClass() { return this.constructor; } } var fluffy = new Cat(); ... var AlsoCat = fluffy.getClass(); var ruffles = new AlsoCat(); ruffles.meow(); // "meow!" 

如果您从getClass方法实例化类,请确保将其包装在括号中,例如: ruffles = new ( fluffy.getClass() )( args... );

在JavaScript中,没有类,但我认为你想要的构造函数名和obj.constructor.toString()会告诉你你需要什么。

同意dfa,这就是为什么我认为prototye作为没有命名的类find类

这是Eli Gray发布的升级function,以配合我的思维方式

 function what(obj){ if(typeof(obj)==="undefined")return "undefined"; if(obj===null)return "Null"; var res = Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1]; if(res==="Object"){ res = obj.constructor.name; if(typeof(res)!='string' || res.length==0){ if(obj instanceof jQuery)return "jQuery";// jQuery build stranges Objects if(obj instanceof Array)return "Array";// Array prototype is very sneaky return "Object"; } } return res; } 

下面是getClass()getInstance()

您可以使用window获取对象的类的引用。

从实例上下文:

 function A() { this.getClass = function() { return window[this.constructor.name]; } this.getNewInstance = function() { return new window[this.constructor.name]; } } var a = new A(); console.log(a.getClass()); // function A { // etc... } // you can even: var b = new a.getClass(); b instanceof A; // true 

从静态上下文:

 function B() {}; B.getClass = function() { return window[this.name]; } B.getInstance() { return new window[this.name]; } 

我现在有一个工作通用的情况,并使用它:

 class Test { // your class definition } nameByType = function(type){ return type.prototype["constructor"]["name"]; }; console.log(nameByType(Test)); 

这是唯一的方法,我发现通过typesinput获取类名,如果你没有一个对象的实例。

(写在ES2017)

点符号也工作正常

 console.log(Test.prototype.constructor.name); // returns "Test" 

Javascript是一个没有类的语言:没有类像Java一样静态地定义一个类的行为。 JavaScript使用原型而不是类来定义对象属性,包括方法和inheritance。 有可能在JavaScript中用原型来模拟许多基于类的特性。

为了保持向后兼容性的ECMAScript 6,JavaScript仍然没有classtypes(尽pipe不是每个人都明白这一点)。 它有一个class关键字作为创build原型的class语法的一部分 – 但仍然没有任何东西叫做class 。 JavaScript不是现在, 从来没有经典的OOP语言 。 谈到JS的类,只是误导或标志尚未grookking原型inheritance(只是保持真实)。

这意味着this.constructor仍然是获取对constructor函数的引用的好方法。 而this.constructor.prototype是访问原型本身的方式。 由于这不是Java,所以不是一个类。 这是你的实例实例化的原型对象。 下面是一个使用ES6语法糖创build原型链的例子:

 class Foo { get foo () { console.info(this.constructor, this.constructor.name) return 'foo' } } class Bar extends Foo { get foo () { console.info('[THIS]', this.constructor, this.constructor.name, Object.getOwnPropertyNames(this.constructor.prototype)) console.info('[SUPER]', super.constructor, super.constructor.name, Object.getOwnPropertyNames(super.constructor.prototype)) return `${super.foo} + bar` } } const bar = new Bar() console.dir(bar.foo) 

这是使用babel-node输出的内容:

 > $ babel-node ./foo.js ⬡ 6.2.0 [±master ●] [THIS] [Function: Bar] 'Bar' [ 'constructor', 'foo' ] [SUPER] [Function: Foo] 'Foo' [ 'constructor', 'foo' ] [Function: Bar] 'Bar' 'foo + bar' 

你有它! 在2016年,JavaScript中有一个class关键字,但仍然没有类的types。 this.constructor是获得构造函数的最好方法, this.constructor.prototype是访问原型本身的最好方法。

问题似乎已经回答了,但是OP想要访问类和对象,就像我们在Java中所做的一样,所选的答案是不够的(imho)。

通过下面的解释,我们可以得到一个对象的类(它实际上被称为JavaScript中的原型)。

 var arr = new Array('red', 'green', 'blue'); var arr2 = new Array('white', 'black', 'orange'); 

你可以像这样添加一个属性:

 Object.defineProperty(arr,'last', { get: function(){ return this[this.length -1]; } }); console.log(arr.last) // blue 

.last属性只能用于从Array原型实例化的“ arr ”对象。 因此,为了让.last属性可用于从Array原型实例化的所有对象,我们必须为Array原型定义.last属性:

 Object.defineProperty(Array.prototype,'last', { get: function(){ return this[this.length -1]; } }); console.log(arr.last) // blue console.log(arr2.last) // orange 

这里的问题是,你必须知道' arr '和' arr2 'variables属于哪个对象types(原型)! 换句话说,如果您不知道“ arr ”对象的types(原型),那么您将无法为它们定义属性。 在上面的例子中,我们知道arr是Array对象的实例,这就是为什么我们使用Array.prototype来为Array定义一个属性。 但是如果我们不知道“ arr ”的类(原型)呢?

 Object.defineProperty(arr.__proto__,'last2', { get: function(){ return this[this.length -1]; } }); console.log(arr.last) // blue console.log(arr2.last) // orange 

正如你所看到的,在不知道' arr '是一个数组的情况下,我们可以通过使用' arr.__proto__ '来添加一个新的属性来引用' arr '的类。

我们访问了' arr '的原型而不知道它是Array的一个实例,我想这就是OP所要求的。