是否有一个JavaScript的等效的Java的class.getName()?
class.getName()
是否有与Java等效的JavaScript class.getName()?
没有 。
名称class Foo {}为Foo.name。thing不论类别如何,的类别名称thing均为thing.constructor.name。ES2015环境中的内置构造函数具有正确的name属性;例如(2).constructor.name是"Number"。
class Foo {}
Foo.name
thing
thing.constructor.name
name
(2).constructor.name
"Number"
但是,这里有各种各样的骇客,它们都以一种或另一种方式下降:
这是一种可以满足您需要的技巧-请注意,它会修改Object的原型,而人们对此并不满意(通常是出于充分的理由)
Object.prototype.getName = function() { var funcNameRegex = /function (.{1,})\(/; var results = (funcNameRegex).exec((this).constructor.toString()); return (results && results.length > 1) ? results[1] : ""; };
现在,所有对象都将具有函数,该函数getName()将以字符串形式返回构造函数的名称。我已经在FF3和中对此进行了测试IE7,不能说其他实现。
getName()
FF3
IE7
如果您不想这样做,这里是讨论在JavaScript中确定类型的各种方法…
我最近将其更新为更详尽,尽管并非如此。欢迎更正…
constructor
每个属性object都有其值constructor,但是取决于该值的object构造方式以及您要使用该值做什么,它可能有用也可能没有用。
object
一般来说,您可以使用constructor属性来测试对象的类型,如下所示:
var myArray = [1,2,3]; (myArray.constructor == Array); // true
因此,这足以满足大多数需求。那就是…
将无法正常工作 在所有 在许多情况下,
这种模式虽然很复杂,但却很常见:
function Thingy() { } Thingy.prototype = { method1: function() { }, method2: function() { } };
Objects通过构造的newThingy将具有constructor指向而Object不是的属性Thingy。因此,我们一开始就陷入困境;您根本无法信任constructor您无法控制的代码库。
Objects
newThingy
Object
Thingy
多重继承
一个不那么明显的例子是使用多重继承:
function a() { this.foo = 1;} function b() { this.bar = 2; } b.prototype = new a(); // b inherits from a
事情现在无法正常运行,因为您可能希望它们:
var f = new b(); // instantiate a new object with the b constructor (f.constructor == b); // false (f.constructor == a); // true
因此,如果object您的测试的object设置不同,则可能会得到意外的结果prototype。在此讨论范围之外,还有其他解决方法。
prototype
该constructor物业还有其他用途,其中一些很有趣,而其他则不是很多。目前,我们将不深入研究这些用途,因为它与本次讨论无关。
无法跨框架和跨窗口工作
使用.constructor进行类型检查时要检查从不同的未来对象的类型将打破window对象,说的iframe或弹出式窗口。这是因为constructor在每个“窗口”中每种核心类型都有不同的版本,即
.constructor
window
iframe.contentWindow.Array === Array // false
instanceof
该instanceof运营商正在测试的一个干净的方式object式为好,但有自己潜在的问题,就像constructor财产。
var myArray = [1,2,3]; (myArray instanceof Array); // true (myArray instanceof Object); // true
但是instanceof对于文字值无效(因为文字不是Objects)
3 instanceof Number // false 'abc' instanceof String // false true instanceof Boolean // false
该文本需要被包裹在一个Object为了instanceof工作,例如
new Number(3) instanceof Number // true
该.constructor检查对于文字是很好的,因为.方法调用隐式地将文字包装在它们各自的对象类型中
.
3..constructor === Number // true 'abc'.constructor === String // true true.constructor === Boolean // true
为什么两个点为3?因为Javascript将第一个点解释为小数点;)
instanceof出于与constructor属性检查相同的原因,也无法在不同的窗口中工作。
同样,见上文;constructor完全完全错误且无用是很常见的。
myObjectInstance.constructor.name
对于IE9及更高版本,您可以进行monkey-patch in support::
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) { Object.defineProperty(Function.prototype, 'name', { get: function() { var funcNameRegex = /function\s+([^\s(]+)\s*\(/; var results = (funcNameRegex).exec((this).toString()); return (results && results.length > 1) ? results[1] : ""; }, set: function(value) {} }); }
有关文章的更新版本。此功能是在文章发布三个月后添加的,这是本文作者Matthew Scharley推荐使用的版本。这种变化是受到注释的启发,这些注释指出了先前代码中的潜在陷阱。
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) { Object.defineProperty(Function.prototype, 'name', { get: function() { var funcNameRegex = /function\s([^(]{1,})\(/; var results = (funcNameRegex).exec((this).toString()); return (results && results.length > 1) ? results[1].trim() : ""; }, set: function(value) {} }); }
事实证明,正如本文所详述的那样,您可以使用Object.prototype.toString-的低级通用实现toString-获取所有内置类型的类型
Object.prototype.toString
toString
Object.prototype.toString.call('abc') // [object String] Object.prototype.toString.call(/abc/) // [object RegExp] Object.prototype.toString.call([1,2,3]) // [object Array]
可以编写一个简短的辅助函数,例如
function type(obj){ return Object.prototype.toString.call(obj).slice(8, -1); }
删除残留物并获取类型名称
type('abc') // String
但是,它将Object为所有用户定义的类型返回。
所有这些都面临一个潜在的问题,那就是有关对象的构造方法。以下是构建对象的各种方式以及不同类型检查方法将返回的值:
// using a named function: function Foo() { this.a = 1; } var obj = new Foo(); (obj instanceof Object); // true (obj instanceof Foo); // true (obj.constructor == Foo); // true (obj.constructor.name == "Foo"); // true // let's add some prototypical inheritance function Bar() { this.b = 2; } Foo.prototype = new Bar(); obj = new Foo(); (obj instanceof Object); // true (obj instanceof Foo); // true (obj.constructor == Foo); // false (obj.constructor.name == "Foo"); // false // using an anonymous function: obj = new (function() { this.a = 1; })(); (obj instanceof Object); // true (obj.constructor == obj.constructor); // true (obj.constructor.name == ""); // true // using an anonymous function assigned to a variable var Foo = function() { this.a = 1; }; obj = new Foo(); (obj instanceof Object); // true (obj instanceof Foo); // true (obj.constructor == Foo); // true (obj.constructor.name == ""); // true // using object literal syntax obj = { foo : 1 }; (obj instanceof Object); // true (obj.constructor == Object); // true (obj.constructor.name == "Object"); // true
尽管这组示例中没有所有排列,但希望有足够的信息可以让您了解根据您的需求情况如何变得凌乱。不要假设任何事情,如果您不完全了解所要追求的目标,则可能会由于缺乏精妙之处而导致代码意外中断。
对typeof运算符的讨论似乎是一个明显的遗漏,但object由于它非常简单,因此在帮助识别an 是否为给定类型方面确实没有用。了解在哪里typeof有用很重要,但是我目前不认为这与本次讨论非常相关。但我的思想是开放的。:)
typeof