我创建了一个JavaScript对象,但是如何确定该对象的类呢?
我想要类似Java的.getClass()
方法。
class
类型。它确实具有用于创建原型的class
关键字和class
语法,可以在其中更轻松地访问方法super
。
我创建了一个JavaScript对象,但是如何确定该对象的类呢?
我想要类似Java的.getClass()
方法。
class
类型。它确实具有用于创建原型的class
关键字和class
语法,可以在其中更轻松地访问方法super
。
Answers:
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编译代码,它将更改非全局类名。为了防止这种情况,丑化有--mangle
PARAM,你可以设置为false使用一饮而尽或呼噜声。
func.prototype
(是的,函数是对象,但是prototype
属性仅与函数对象相关)。
instanceof
/ isPrototypeOf()
和非标准__proto__
Object.getPrototypeOf()
constructor.name
如果您的代码正在缩小,请不要依赖。函数名称将任意更改。
construction.name
认为是要忽略的令牌,而不是将其最小化。除了大多数(如果不是全部),minifier软件还提供例外规则。
obj.constructor.name
在现代浏览器中是一种可靠的方法。Function.name
已在ES6中正式添加到该标准中,从而使这成为将JavaScript对象的“类”作为字符串获取的符合标准的方法。如果对象被实例化var obj = new MyClass()
,它将返回“ MyClass”。
它将为数字返回“ Number”,为数组返回“ Array”,为函数返回“ Function”,等等。它的行为通常与预期的一样。失败的唯一情况是通过原型创建了没有原型Object.create( null )
的对象,或者该对象是从匿名定义(未命名)的函数实例化的。
还要注意,如果要压缩代码,则与硬编码类型字符串进行比较是不安全的。例如,不检查是否obj.constructor.name == "MyType"
,而是检查obj.constructor.name == MyType.name
。或者只是比较构造函数本身,但是这将无法跨DOM边界,因为每个DOM上都有不同的构造函数实例,因此无法在其构造函数上进行对象比较。
Function.name
还不是JavaScript标准的一部分。Chrome和Firefox当前支持该功能,但IE(10)不支持。
obj.constructor.name
仅适用于命名函数。即,如果我定义var Foo = function() {}
,则for var foo = new Foo()
,foo.constructor.name
将为您提供空字符串。
constructor.name
如果您的代码正在缩小,请不要依赖。函数名称将任意更改。
constructor.name
ES6中的新类支持行为符合预期。
此函数返回"Undefined"
未定义的值和"Null"
null。
对于所有其他值,CLASSNAME
-part是从中提取的[object CLASSNAME]
,这是使用的结果Object.prototype.toString.call(value)
。
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...
"Object"
。
return obj.constructor.name
。这样可以得到相同的结果,并且还可以处理非本机对象。
要获取“伪类”,您可以通过以下方式获取构造函数
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
为了保持其向后兼容的不间断记录ECMAScript 6,JavaScript仍然没有class
类型(尽管不是每个人都理解这一点)。它确实在创建原型时将class
关键字作为其class
语法的一部分,但仍然没有一个叫做class的东西。JavaScript现在不是,并且从来都不是经典的OOP语言。从类的角度讲JS只是一种误导,或者是尚未取消原型继承的迹象(只是保持它的真实性)。
这意味着this.constructor
仍然是引用该constructor
函数的好方法。并且this.constructor.prototype
是访问原型本身的方法。由于这不是Java,所以它不是类。这是实例从中实例化的原型对象。这是一个使用ES6语法糖创建原型链的示例:
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年,class
JavaScript中有一个关键字,但仍然没有类类型。this.constructor
是获取构造函数this.constructor.prototype
的最佳方法,也是访问原型本身的最佳方法。
我现在有一种情况可以通用工作,并使用了以下方法:
class Test {
// your class definition
}
nameByType = function(type){
return type.prototype["constructor"]["name"];
};
console.log(nameByType(Test));
如果您没有对象的实例,那就是我发现通过类型输入获取类名称的唯一方法。
(用ES2017编写)
点符号也可以
console.log(Test.prototype.constructor.name); // returns "Test"
对于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... );
我在IE中找到object.constructor.toString()
返回[object objectClass]
,而不是function objectClass () {}
在chome中返回。因此,我认为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;
};
在javascript中,没有任何类,但是我认为您需要构造函数名称,obj.constructor.toString()
并将告诉您所需的内容。
.name
。
.name
即使在IE 9上也没有定义
同意dfa,这就是为什么在找不到命名类的情况下我将原型视为该类的原因
这是Eli Grey发布的功能的升级功能,以符合我的想法
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()
您可以使用来获取对象类的引用this.constructor
。
function A() {
this.getClass = function() {
return this.constructor;
}
this.getNewInstance = function() {
return new this.constructor;
}
}
var a = new A();
console.log(a.getClass()); // function A { // etc... }
// you can even:
var b = new (a.getClass());
console.log(b instanceof A); // true
var c = a.getNewInstance();
console.log(c instanceof A); // true
function A() {};
A.getClass = function() {
return this;
}
A.getInstance() {
return new this;
}
this.constructor
呢?
你也可以做这样的事情
class Hello {
constructor(){
}
}
function isClass (func) {
return typeof func === 'function' && /^class\s/.test(Function.prototype.toString.call(func))
}
console.log(isClass(Hello))
这将告诉您输入是否为类
Javascript是一种无类语言:没有类可以像Java中一样静态地定义类的行为。JavaScript使用原型而不是类来定义对象属性,包括方法和继承。使用JavaScript中的原型可以模拟许多基于类的功能。
class
类型。它确实具有用于创建原型的class
关键字和class
语法,可以在其中更轻松地访问方法super
。
问题似乎已经回答了,但OP希望访问和对象的类,就像我们在Java中所做的那样,所选答案还不够(恕我直言)。
通过以下解释,我们可以获得对象的类(实际上在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
属性仅可用于arr
从Array原型实例化的' '对象。因此,为了使该.last
属性可用于从Array原型实例化的所有对象,我们必须定义.last
Array原型的属性:
Object.defineProperty(Array.prototype,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
这里的问题是,您必须知道' arr
'和' arr2
'变量属于哪个对象类型(原型)!换句话说,如果您不知道' arr
'对象的类类型(原型),则将无法为其定义属性。在上面的示例中,我们知道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
通过使用' 引用' ' 的类来添加新属性。arr.__proto__
'。
我们访问了'的原型,arr
却不知道它是Array的一个实例,我认为这就是OP的要求。
__proto__
属性已弃用,并且几乎没有任何优势prototype
。