Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
296 views
in Technique[技术] by (71.8m points)

javascript - 获取对象类型的名称(Get the name of an object's type)

有JavaScript相当于Java的class.getName()吗?

  ask by Ewen Cartwright translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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. (我已经在FF3IE7对此进行了测试,我不能说其他实现。)

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. (每个objectconstructor属性都有一个值,但是取决于该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而不是Thingyconstructor属性。) 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. (这种变化是受到注释的启发,这些注释指出了先前代码中的潜在陷阱 。)

if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
    Object.defineProperty(Function.prototype, 'name', {
        get: function() {
            var funcNameRegex = /functions([^(]{1,})(/;
            var results = 

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...