JavaScript中是否有类似Java的class.getName()?
当前回答
好吧,伙计们,我一直在慢慢地建立一个catch all方法,这已经有几年了,哈哈!诀窍是:
有一个创建类的机制。 有一种机制来检查所有用户创建的类、原语和由本地构造函数创建/生成的值。 有一种机制可以将用户创建的类扩展为新的类,这样上述功能就可以渗透到你的代码/应用程序/库等中。
举个例子(或者看看我是如何处理这个问题的),看看github上的以下代码:https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js并搜索:
名为= classOf class sofis =,和或 defineSubClass =(不带反撇号('))。
As you can see I have some mechanisms in place to force classOf to always give me the classes/constructors type name regardless of whether it is a primitive, a user defined class, a value created using a native constructor, Null, NaN, etc.. For every single javascript value I will get it's unique type name from the classOf function. In addition I can pass in actual constructors into sjl.classOfIs to check a value's type in addition to being able to pass in it's type name as well! So for example:
' ' ' //请原谅长命名空间!直到用了一段时间后,我才知道它的影响(它们太糟糕了,哈哈)
var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
constructor: function SomeCustomClass () {},
// ...
}),
HelloIterator = sjl.ns.stdlib.Iterator.extend(
function HelloIterator () {},
{ /* ... methods here ... */ },
{ /* ... static props/methods here ... */ }
),
helloIt = new HelloIterator();
sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`
var someString = 'helloworld';
sjl.classOfIs(someString, String) === true; // `true`
sjl.classOfIs(99, Number) === true; // true
sjl.classOf(NaN) === 'NaN'; // true
sjl.classOf(new Map()) === 'Map';
sjl.classOf(new Set()) === 'Set';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`
// etc..
// Also optionally the type you want to check against could be the type's name
sjl.classOfIs(['a', 'b', 'c'], 'Array') === true; // `true`!
sjl.classOfIs(helloIt, 'HelloIterator') === true; // `true`!
```
如果您有兴趣阅读更多关于我如何使用上面提到的设置,请查看repo: https://github.com/elycruz/sjljs
还有关于这个主题的书籍: - Stoyan Stefanov的《JavaScript模式》 - David Flanagan的《Javascript - The Definitive Guide》 ——还有其他很多人…(搜索le’web)。
你也可以快速测试我在这里谈论的功能: - http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (url中的0.5.18路径也有来自github的源代码,减去node_modules等)。
编码快乐!
其他回答
下面是我提出的解决instanceof缺点的解决方案。它可以从跨窗口和跨框架检查对象的类型,并且在基本类型方面没有问题。
function getType(o) {
return Object.prototype.toString.call(o).match(/^\[object\s(.*)\]$/)[1];
}
function isInstance(obj, type) {
var ret = false,
isTypeAString = getType(type) == "String",
functionConstructor, i, l, typeArray, context;
if (!isTypeAString && getType(type) != "Function") {
throw new TypeError("type argument must be a string or function");
}
if (obj !== undefined && obj !== null && obj.constructor) {
//get the Function constructor
functionConstructor = obj.constructor;
while (functionConstructor != functionConstructor.constructor) {
functionConstructor = functionConstructor.constructor;
}
//get the object's window
context = functionConstructor == Function ? self : functionConstructor("return window")();
//get the constructor for the type
if (isTypeAString) {
//type is a string so we'll build the context (window.Array or window.some.Type)
for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
context = context[typeArray[i]];
}
} else {
//type is a function so execute the function passing in the object's window
//the return should be a constructor
context = type(context);
}
//check if the object is an instance of the constructor
if (context) {
ret = obj instanceof context;
if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
ret = obj.constructor == context
}
}
}
return ret;
}
isInstance需要两个参数:一个对象和一个类型。它工作的真正技巧是检查对象是否来自同一个窗口,如果不是,则获取对象的窗口。
例子:
isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false
type参数也可以是返回构造函数的回调函数。回调函数将接收一个参数,该参数是所提供对象的窗口。
例子:
//"Arguments" type check
var args = (function() {
return arguments;
}());
isInstance(args, function(w) {
return w.Function("return arguments.constructor")();
}); //true
//"NodeList" type check
var nl = document.getElementsByTagName("*");
isInstance(nl, function(w) {
return w.document.getElementsByTagName("bs").constructor;
}); //true
需要记住的一件事是IE < 9没有提供所有对象的构造函数,因此上面的NodeList测试将返回false,而且isInstance(alert,“Function”)也将返回false。
非常简单!
我最喜欢在JS中获取任何类型的方法
function getType(entity){
var x = Object.prototype.toString.call(entity)
return x.split(" ")[1].split(']')[0].toLowerCase()
}
我最喜欢的检查JS中任何类型的方法
function checkType(entity, type){
return getType(entity) === type
}
对于那些读到这篇文章,想要一个相当有效且经过测试的简单解决方案的人:
const getTypeName = (thing) => {
const name = typeof thing
if (name !== 'object') return name
if (thing instanceof Error) return 'error'
if (!thing) return 'null'
return ({}).toString.call(thing).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
要深入了解其工作原理,请签出Array.isArray()的polyfill文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#polyfill
Jason Bunting的回答给了我足够的线索,让我找到我需要的东西:
<<Object instance>>.constructor.name
例如,在下面这段代码中:
function MyObject() {}
var myInstance = new MyObject();
myinstance。constructor.name将返回"MyObject"。
使用class.name。这也适用于function.name。
class TestA {}
console.log(TestA.name); // "TestA"
function TestB() {}
console.log(TestB.name); // "TestB"