Is there a JavaScript equivalent of Java's class.getName()
?
(有JavaScript相当于Java的class.getName()
吗?)
No .
(不行)
ES2015 Update : the name of class Foo {}
is Foo.name
.
(ES2015更新 : class Foo {}
的名称为Foo.name
。)
The name of thing
's class, regardless of thing
's type, is thing.constructor.name
.(名称thing
的类,不管thing
的类型,是thing.constructor.name
。)
Builtin constructors in an ES2015 environment have the correct name
property;(ES2015环境中的内置构造函数具有正确的name
属性;)
for instance (2).constructor.name
is "Number"
.(例如(2).constructor.name
是"Number"
。)
But here are various hacks that all fall down in one way or another:
(但是,这里有各种各样的骇客,它们都以一种或另一种方式下降:)
Here is a hack that will do what you need - be aware that it modifies the Object's prototype, something people frown upon (usually for good reason)
(这是一种可以满足您需要的技巧-请注意,它会修改Object的原型,而人们对此并不满意(通常是出于充分的理由))
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
Now, all of your objects will have the function, getName()
, that will return the name of the constructor as a string.
(现在,所有对象都将具有getName()
函数,该函数将以字符串形式返回构造函数的名称。)
I have tested this in FF3
and IE7
, I can't speak for other implementations.(我已经在FF3
和IE7
对此进行了测试,我不能说其他实现。)
If you don't want to do that, here is a discussion on the various ways of determining types in JavaScript...
(如果您不想这样做,这里将讨论确定JavaScript中类型的各种方法...)
I recently updated this to be a bit more exhaustive, though it is hardly that.
(我最近将其更新为更加详尽,尽管并非如此。)
Corrections welcome...(欢迎更正...)
Using the constructor
property...(使用constructor
属性...)
Every object
has a value for its constructor
property, but depending on how that object
was constructed as well as what you want to do with that value, it may or may not be useful.
(每个object
的constructor
属性都有一个值,但是取决于该object
构造方式以及您要对该值进行的操作,它可能有用也可能没有用。)
Generally speaking, you can use the constructor
property to test the type of the object like so:
(一般来说,可以使用constructor
属性来测试对象的类型,如下所示:)
var myArray = [1,2,3];
(myArray.constructor == Array); // true
So, that works well enough for most needs.
(因此,这足以满足大多数需求。)
That said...(那个...)
Caveats(注意事项)
Will not work AT ALL in many cases
(会不会在很多情况下, 在所有的工作)
This pattern, though broken, is quite common:
(这种模式虽然很复杂,但却很常见:)
function Thingy() {
}
Thingy.prototype = {
method1: function() {
},
method2: function() {
}
};
Objects
constructed via new Thingy
will have a constructor
property that points to Object
, not Thingy
.
(通过new Thingy
构造的Objects
将具有指向Object
而不是Thingy
的constructor
属性。)
So we fall right at the outset;(因此,我们一开始就陷入困境;)
you simply cannot trust constructor
in a codebase that you don't control.(您根本无法信任您无法控制的代码库中的constructor
。)
Multiple Inheritance
(多重继承)
An example where it isn't as obvious is using multiple inheritance:
(一个不那么明显的例子是使用多重继承:)
function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a
Things now don't work as you might expect them to:
(事情现在不起作用,您可能希望它们能够:)
var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true
So, you might get unexpected results if the object
your testing has a different object
set as its prototype
.
(所以,你可能会得到意想不到的结果,如果object
您的测试有不同的object
设置为其prototype
。)
There are ways around this outside the scope of this discussion.(在此讨论范围之外,还有其他解决方法。)
There are other uses for the constructor
property, some of them interesting, others not so much;
(constructor
属性还有其他用途,其中一些很有趣,而其他则不是很多。)
for now we will not delve into those uses since it isn't relevant to this discussion.(目前我们不会深入研究这些用途,因为它与本次讨论无关。)
Will not work cross-frame and cross-window
(无法跨框架和跨窗口工作)
Using .constructor
for type checking will break when you want to check the type of objects coming from different window
objects, say that of an iframe or a popup window.
(当您要检查来自不同window
对象(例如iframe或弹出窗口)的对象的类型时,使用.constructor
进行类型检查会中断。)
This is because there's a different version of each core type constructor
in each `window', ie(这是因为每个“窗口”中每个核心类型constructor
都有不同的版本,即)
iframe.contentWindow.Array === Array // false
Using the instanceof
operator...(使用instanceof
运算子...)
The instanceof
operator is a clean way of testing object
type as well, but has its own potential issues, just like the constructor
property.
(instanceof
运算符也是一种测试object
类型的干净方法,但是与constructor
属性一样,它也有其自身的潜在问题。)
var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true
But instanceof
fails to work for literal values (because literals are not Objects
)
(但是instanceof
不能用于文字值(因为文字不是Objects
))
3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false
The literals need to be wrapped in an Object
in order for instanceof
to work, for example
(为了使instanceof
正常工作,这些文字需要包装在一个Object
中,例如)
new Number(3) instanceof Number // true
The .constructor
check works fine for literals because the .
(.constructor
检查适用于文字,因为.
)
method invocation implicitly wraps the literals in their respective object type(方法调用隐式地将文字包装在它们各自的对象类型中)
3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true
Why two dots for the 3?
(为什么两个点为3?)
Because Javascript interprets the first dot as a decimal point ;)(因为Javascript将第一个点解释为小数点;))
Will not work cross-frame and cross-window(无法跨框架和跨窗口工作)
instanceof
also will not work across different windows, for the same reason as the constructor
property check.
(出于与constructor
属性检查相同的原因, instanceof
也无法在不同的窗口中运行。)
Using the name
property of the constructor
property...(使用constructor
属性的name
属性...)
Does not work AT ALL in many cases(没有在很多情况下, 在所有的工作)
Again, see above;
(同样,见上文;)
it's quite common for constructor
to be utterly and completely wrong and useless.(constructor
完全完全错误且无用的情况非常普遍。)
Does NOT work in <IE9(在<IE9中不起作用)
Using myObjectInstance.constructor.name
will give you a string containing the name of the constructor
function used, but is subject to the caveats about the constructor
property that were mentioned earlier.
(使用myObjectInstance.constructor.name
将为您提供一个字符串,其中包含所使用的constructor
函数的名称,但是要遵守前面提到的有关constructor
属性的注意事项。)
For IE9 and above, you can monkey-patch in support :
(对于IE9及更高版本,您可以通过猴子补丁获得支持 :)
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /functions+([^s(]+)s*(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1] : "";
},
set: function(value) {}
});
}
Updated version from the article in question.
(有关文章的更新版本 。)
This was added 3 months after the article was published, this is the recommended version to use by the article's author Matthew Scharley.(此功能是在文章发布后3个月添加的,这是本文作者Matthew Scharley推荐使用的版本。)
This change was inspired by comments pointing out potential pitfalls in the previous code.(这种变化是受到注释的启发,这些注释指出了先前代码中的<a href="https://stackoom.com/link/aHR0cDovL21hdHQuc2NoYXJsZXkubWUvMjAxMi8wMy9tb25rZXktcGF0Y2gtbmFtZS1pZS5odG1sI2NvbW1lbnQtNTUxNjU0MDk2" rel="nofollow noopener" targe